Logo ROOT   6.18/05
Reference Guide
TPackMgr.cxx
Go to the documentation of this file.
1// @(#)root/proof:$Id$
2// Author: G. Ganis, Oct 2015
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TPackMgr
13\ingroup proofkernel
14
15The PROOF package manager contains tools to manage packages.
16This class has been created to eliminate duplications, and to allow for
17standalone usage.
18
19*/
20
21#include "TPackMgr.h"
22
23#include "TError.h"
24#include "TFile.h"
25#include "TFunction.h"
26#include "THashList.h"
27#include "TList.h"
28#include "TMacro.h"
29#include "TMD5.h"
30#include "TMethodArg.h"
31#include "TMethodCall.h"
32#include "TObjString.h"
33#include "TParameter.h"
34#include "TMap.h"
35#include "TProof.h" // for constants such as kRM and kLS.
36#include "TROOT.h"
37#include "TSystem.h"
38
40
41
42static void DefaultLogger(const char *msg) { Printf("%s", msg); }
43
44THashList *TPackMgr::fgGlobalPackMgrList = 0; // list of package managers for global packages
45
46////////////////////////////////////////////////////////////////////////////////
47/// Create a PROOF package manager
48
49TPackMgr::TPackMgr(const char *dir, const char *key)
50 : fLogger(DefaultLogger), fName(key), fDir(dir), fLock(dir), fEnabledPackages(0)
51{
52 // Work with full names
54 Warning("TPackMgr", "problems expanding path '%s'", fDir.Data());
55 // The lock file in temp
56 TString lockname = TString::Format("%s/packdir-lock-%s",
57 gSystem->TempDirectory(), TString(fDir).ReplaceAll("/","%").Data());
58 fLock.SetName(lockname);
59}
60
61////////////////////////////////////////////////////////////////////////////////
62/// Destroy a TPackMgr instance
63
65{
66 // Destroy the lock file
68}
69
70////////////////////////////////////////////////////////////////////////////////
71/// Wrapper to notofuer / logger
72
73void TPackMgr::Log(const char *msg)
74{
75 if (fLogger) {
76 if (fPfx.IsNull())
77 (*fLogger)(msg);
78 else
79 (*fLogger)(TString::Format("%s: %s", fPfx.Data(), msg));
80 }
81}
82
83////////////////////////////////////////////////////////////////////////////////
84/// Method to build a package.
85/// Return -1 on error, 0 otherwise
86
87Int_t TPackMgr::Build(const char *pack, Int_t opt)
88{
89 Int_t rc = 0;
90
92
93 if (gDebug > 0)
94 Info("Build", "building package %s ...", pack);
95
97 TString pdir = TString::Format("%s/%s", fDir.Data(), pack);
99
100 // check for BUILD.sh and execute
101 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
102 // Notify the upper level
103 Log(TString::Format("building %s ...", pack));
104
105 // Read version from file proofvers.txt, and if current version is
106 // not the same do a "BUILD.sh clean"
107 Bool_t goodver = kTRUE;
108 Bool_t savever = kFALSE;
109 TString v, r;
110 FILE *f = fopen("PROOF-INF/proofvers.txt", "r");
111 if (f) {
112 v.Gets(f);
113 r.Gets(f);
114 fclose(f);
115 if (opt == TPackMgr::kCheckROOT && v != gROOT->GetVersion()) goodver = kFALSE;
116 }
117 if (!f || !goodver) {
119 savever = kTRUE;
120 Log(TString::Format("%s: version change"
121 " (current: %s, build: %s): cleaning ... ",
122 pack, gROOT->GetVersion(), v.Data()));
123 // Hard cleanup: go up the dir tree
125 // remove package directory
126 gSystem->Exec(TString::Format("%s %s", kRM, pdir.Data()));
127 // find gunzip...
128 char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP,
130 if (gunzip) {
131 TString par;
132 par.Form("%s.par", pdir.Data());
133 // untar package
134 TString cmd;
135 cmd.Form(kUNTAR3, gunzip, par.Data());
136 rc = gSystem->Exec(cmd);
137 if (rc != 0) {
138 Error("Build", "failure executing: %s", cmd.Data());
139 } else {
140 // Store md5 in package/PROOF-INF/md5.txt
141 TMD5 *md5local = TMD5::FileChecksum(par);
142 if (md5local) {
143 TString md5f = pdir + "/PROOF-INF/md5.txt";
144 TMD5::WriteChecksum(md5f, md5local);
145 // Go down to the package directory
147 // Cleanup
148 SafeDelete(md5local);
149 } else {
150 Warning("Build", "failure calculating/saving MD5sum for '%s'", par.Data());
151 }
152 }
153 delete [] gunzip;
154 } else {
155 Error("Build", "%s not found", kGUNZIP);
156 rc = -1;
157 }
158 } else {
159 Log(TString::Format("%s: ROOT version inconsistency (current: %s, build: %s):"
160 " directory not writable: cannot re-build!!! ",
161 pack, gROOT->GetVersion(), v.Data()));
162 rc = -1;
163 }
164
165 if (rc == 0) {
166 // To build the package we execute PROOF-INF/BUILD.sh via a pipe
167 // so that we can send back the log in (almost) real-time to the
168 // (impatient) client. Note that this operation will block, so
169 // the messages from builds on the workers will reach the client
170 // shortly after the master ones.
172 ipath.ReplaceAll("\"","");
173 TString cmd;
174 cmd.Form("export ROOTINCLUDEPATH=\"%s\" ; PROOF-INF/BUILD.sh", ipath.Data());
175 rc = gSystem->Exec(cmd);
176 if (rc != 0) {
177 Error("Build", "failure executing: %s", cmd.Data());
178 } else {
179 // Success: write version file
180 if (savever) {
181 f = fopen("PROOF-INF/proofvers.txt", "w");
182 if (f) {
183 fputs(gROOT->GetVersion(), f);
184 fputs(TString::Format("\n%s", gROOT->GetGitCommit()), f);
185 fclose(f);
186 }
187 }
188 }
189 }
190 } else {
191 // Notify the user
192 if (gDebug > 0)
193 Info("Build", "no PROOF-INF/BUILD.sh found for package %s", pack);
194 }
195 }
196 // Always return to the initial directory
198
199 return rc;
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Method to load a package taking an option const char *
204/// Return -1 on error, 0 otherwise
205
206Int_t TPackMgr::Load(const char *pack, const char *opts)
207{
208 TList *optls = new TList;
209 optls->Add(new TObjString(opts));
210 Int_t rc = Load(pack, optls);
211 optls->SetOwner();
212 delete optls;
213 return rc;
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Method to load a package taking an option list
218/// Return -1 on error, 0 otherwise
219
220Int_t TPackMgr::Load(const char *pack, TList *optls)
221{
222 Int_t rc = 0;
223 TString emsg;
224
225 // If already loaded don't do it again
227 Log(TString::Format("error: TPackMgr::Load: package %s already loaded", pack));
228 return 0;
229 }
230
231 // Which pack mgr has the package?
232 if (!Has(pack)) {
233 // Check the global packages
234 TPackMgr *packmgr = 0;
235 if (!(packmgr = TPackMgr::GetPackMgr(pack, nullptr))) {
236 // Package not found
237 Log(TString::Format("error: TPackMgr::Load: failure locating %s ...", pack));
238 return -1;
239 }
240 // Load from there
241 return packmgr->Load(pack, optls);
242 }
243
244 // We have the package
245 TString pdir = TString::Format("%s/%s", fDir.Data(), pack);
246
247 // Check dependencies
248 TString deps = TString::Format("%s/PROOF-INF/depends", pdir.Data());
249 if (!gSystem->AccessPathName(deps)) {
250 TMacro mdeps("deps");
251 if (mdeps.ReadFile(deps) > 0) {
252 Log(TString::Format("info: TPackMgr::Load: checking dependencies for package %s ...", pack));
253 TIter nxl(mdeps.GetListOfLines());
254 TObjString *os = 0;
255 while ((os = (TObjString *)nxl())) {
256 if (!TPackMgr::IsEnabled(os->GetName(), this)) {
257 if (Load(os->GetName(), optls) < 0) {
258 // Package loading failure
259 Log(TString::Format("error: TPackMgr::Load: failure loading dep %s ...", os->GetName()));
260 return -1;
261 }
262 }
263 }
264 }
265 }
266
267 // Make sure it has been build
268 Int_t chkveropt = kCheckROOT;
269 if (optls) {
270 TParameter<Int_t> *pcv = (TParameter<Int_t> *) optls->FindObject("PROOF_Package_CheckVersion");
271 if (pcv) {
272 chkveropt = pcv->GetVal();
273 optls->Remove(pcv);
274 delete pcv;
275 }
276 }
277 if (Build(pack, chkveropt) < 0) {
278 // Package not found
279 Log(TString::Format("error: TPackMgr::Load: package %s oes not build! ", pack));
280 return -1;
281 }
282
285
286 // Shared lock from here
288
289 // Check for SETUP.C and execute
290 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
291 // We need to change the name of the function to avoid problems when we load more packages
292 TString setup;
293 setup.Form("SETUP_%d_%x", gSystem->GetPid(), TString(pack).Hash());
294 // Remove special characters
295 TMacro setupmc("PROOF-INF/SETUP.C");
296 TObjString *setupline = setupmc.GetLineWith("SETUP(");
297 if (setupline) {
298 TString setupstring(setupline->GetString());
299 setupstring.ReplaceAll("SETUP(", TString::Format("%s(", setup.Data()));
300 setupline->SetString(setupstring);
301 } else {
302 // Macro does not contain SETUP()
303 Log(TString::Format("warning: macro '%s/PROOF-INF/SETUP.C' does not contain a SETUP()"
304 " function", pack));
305 }
306
307 // Load the macro
308 if (!setupmc.Load()) {
309 // Macro could not be loaded
310 Log(TString::Format("error: macro '%s/PROOF-INF/SETUP.C' could not be loaded:"
311 " cannot continue", pack));
312 rc = -1;
313 } else {
314 // Check the signature
315 TFunction *fun = (TFunction *) gROOT->GetListOfGlobalFunctions()->FindObject(setup);
316 if (!fun) {
317 // Notify the upper level
318 Log(TString::Format("error: function SETUP() not found in macro '%s/PROOF-INF/SETUP.C':"
319 " cannot continue", pack));
320 rc = -1;
321 } else {
322 TMethodCall callEnv;
323 // Check the number of arguments
324 if (fun->GetNargs() == 0) {
325 // No arguments (basic signature)
326 callEnv.Init(fun);
327 if (optls && optls->GetSize() > 0) {
328 Log(TString::Format("warning: loaded SETUP() for '%s' does not take any argument:"
329 " the specified argument will be ignored", pack));
330 }
331 } else if (fun->GetNargs() == 1) {
332 TMethodArg *arg = (TMethodArg *) fun->GetListOfMethodArgs()->First();
333 if (arg) {
334 callEnv.Init(fun);
335 // Check argument type
336 TString argsig(arg->GetTitle());
337 if (argsig.BeginsWith("TList")) {
338 callEnv.ResetParam();
339 callEnv.SetParam((Long_t) optls);
340 } else if (argsig.BeginsWith("const char")) {
341 callEnv.ResetParam();
342 TObjString *os = optls ? dynamic_cast<TObjString *>(optls->First()) : 0;
343 if (os) {
344 callEnv.SetParam((Long_t) os->GetName());
345 } else {
346 if (optls && optls->First()) {
347 Log(TString::Format("warning: found object argument of type %s:"
348 " SETUP expects 'const char *': ignoring",
349 optls->First()->ClassName()));
350 }
351 callEnv.SetParam((Long_t) 0);
352 }
353 } else {
354 // Notify the upper level
355 Log(TString::Format("error: unsupported SETUP signature: SETUP(%s)"
356 " cannot continue", arg->GetTitle()));
357 rc = -1;
358 }
359 } else {
360 // Notify the upper level
361 Log("error: cannot get information about the SETUP() argument:"
362 " cannot continue");
363 rc = -1;
364 }
365 } else if (fun->GetNargs() > 1) {
366 // Notify the upper level
367 Log("error: function SETUP() can have at most a 'TList *' argument:"
368 " cannot continue");
369 rc = -1;
370 }
371 // Execute
372 Long_t setuprc = (rc == 0) ? 0 : -1;
373 if (rc == 0) {
374 callEnv.Execute(setuprc);
375 if (setuprc < 0) rc = -1;
376 }
377 }
378 }
379 }
380
382
383 if (rc == 0) {
384 // create link to package in working directory
385 gSystem->Symlink(pdir, pack);
386
387 // add package to list of include directories to be searched
388 // by ACliC
389 gSystem->AddIncludePath(TString::Format("-I%s", pack));
390
391 // add package to list of include directories to be searched by CINT
392 gROOT->ProcessLine(TString::Format(".I %s", pack));
393
394 TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pack), optls->Clone())
395 : new TPair(new TObjString(pack), 0);
396 if (!fEnabledPackages) {
399 }
400 fEnabledPackages->Add(pck);
401 }
402
403 return rc;
404}
405
406
407////////////////////////////////////////////////////////////////////////////////
408/// Method to unload a package.
409/// Return -1 on error, 0 otherwise
410
411Int_t TPackMgr::Unload(const char *pack)
412{
413 Int_t rc = 0;
414
416 TPair *ppack = 0;
417 if (pack && strlen(pack) > 0) {
418 if ((ppack = (TPair *) fEnabledPackages->FindObject(pack))) {
419
420 // Remove entry from include path
421 TString aclicincpath = gSystem->GetIncludePath();
422 TString cintincpath = gInterpreter->GetIncludePath();
423 // remove interpreter part of gSystem->GetIncludePath()
424 aclicincpath.Remove(aclicincpath.Length() - cintincpath.Length() - 1);
425 // remove package's include path
426 aclicincpath.ReplaceAll(TString(" -I") + pack, "");
427 gSystem->SetIncludePath(aclicincpath);
428
429 //TODO reset interpreter include path
430
431 // remove entry from enabled packages list
432 delete fEnabledPackages->Remove(ppack);
433 }
434
435 // Cleanup the link, if there
436 if (!gSystem->AccessPathName(pack))
437 if (gSystem->Unlink(pack) != 0) rc = -1;
438
439 } else {
440
441 // Iterate over packages and remove each package
443 while ((ppack = (TPair *) nxp())) {
444 if (Unload(ppack->GetName()) != 0) rc = -1;
445 }
446
447 }
448 }
449
450 // We are done
451 return rc;
452}
453
454////////////////////////////////////////////////////////////////////////////////
455/// Method to check if this package manager has package 'pack'.
456/// Return kTRUE or kFALSE
457
458Bool_t TPackMgr::Has(const char *pack)
459{
460 // always follows BuildPackage so no need to check for PROOF-INF
461 TString pdir = TString::Format("%s/%s", fDir.Data(), pack);
462
463 // Shared lock from here
465
467 gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission))
468 return kFALSE;
469
470 // Relevant directories exist and ar readable
471 return kTRUE;
472}
473
474////////////////////////////////////////////////////////////////////////////////
475/// Method to check if 'path' is in the managed directory
476/// Return kTRUE or kFALSE
477
478Bool_t TPackMgr::IsInDir(const char *path)
479{
480 return strncmp(fDir.Data(), path, fDir.Length()) ? kFALSE : kTRUE ;
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// Method to get the path of the dir for package 'pack'.
485/// Return -1 in case of error (not found), 0 otherwise
486
487Int_t TPackMgr::GetPackDir(const char *pack, TString &pdir)
488{
489 // Make sure the extension is not ".par"
490 TString pn(pack);
491 if (strstr(pack, ".par")) pn.Remove(pn.Last('.'));
492 pdir.Form("%s/%s", fDir.Data(), pn.Data());
493 if (gSystem->AccessPathName(pdir, kReadPermission)) return -1;
494 return 0;
495}
496
497////////////////////////////////////////////////////////////////////////////////
498/// Method to get a semi-colon separated list with the names of the enabled
499/// packages.
500
502{
503 packlist = "";
504 if (!fEnabledPackages) return;
505
507 TPair *pck= 0;
508 while ((pck = (TPair *)nxp())) {
509 if (packlist.Length() <= 0)
510 packlist = pck->GetName();
511 else
512 packlist += TString::Format(";%s", pck->GetName());
513 }
514 return;
515}
516
517////////////////////////////////////////////////////////////////////////////////
518/// Method to get the path of the PAR file for package 'pack'.
519/// Return -1 in case of error (not found), 0 otherwise
520
521Int_t TPackMgr::GetParPath(const char *pack, TString &path)
522{
523 // Make sure the extension is ".par"
524 const char *fm = (strstr(pack, ".par")) ? "%s/%s" : "%s/%s.par";
525 path.Form(fm, fDir.Data(), pack);
526 if (gSystem->AccessPathName(path, kReadPermission)) return -1;
527 return 0;
528}
529
530////////////////////////////////////////////////////////////////////////////////
531/// Method to get the download dir; create if not existing
532/// Return -1 in case of error (not found; not created), 0 otherwise
533
535{
536 dldir.Form("%s/downloaded", fDir.Data());
538 if (gSystem->mkdir(dldir, kTRUE) != 0) return -1;
539 if (gSystem->AccessPathName(dldir, kReadPermission)) return -1;
540 }
541 return 0;
542}
543
544////////////////////////////////////////////////////////////////////////////////
545/// Show available packages
546///
547
548void TPackMgr::Show(const char *title)
549{
551 // Scan the list of global packages dirs
553 TPackMgr *pm = 0;
554 while ((pm = (TPackMgr *)nxpm())) {
555 pm->Show(TString::Format("*** Global Package cache %s %s:%s ***\n",
556 pm->GetName(), gSystem->HostName(), pm->GetTitle()));
557 }
558 }
559
560 if (title && strlen(title) > 0)
561 printf("%s\n", title);
562 else
563 printf("*** Package cache %s:%s ***\n", gSystem->HostName(), fDir.Data());
564 fflush(stdout);
565 // Shared lock from here
567 gSystem->Exec(TString::Format("%s %s", kLS, fDir.Data()));
568 printf("\n");
569}
570
571////////////////////////////////////////////////////////////////////////////////
572/// Clean dir for package 'pack'
573/// Return -1 in case of error, 0 otherwise
574///
575
576Int_t TPackMgr::Clean(const char *pack)
577{
578 // Shared lock from here
580 Int_t rc = 0;
581 if (pack && strlen(pack)) {
582 // remove package directory and par file
583 rc = gSystem->Exec(TString::Format("%s %s/%s/*", kRM, fDir.Data(), pack));
584 }
585 return rc;
586}
587
588////////////////////////////////////////////////////////////////////////////////
589/// Remove package 'pack'
590/// If 'pack' is null or empty all packages are cleared
591///
592
593Int_t TPackMgr::Remove(const char *pack, Bool_t dolock)
594{
595 // Shared lock from here
596 if (dolock) fLock.Lock();
597 Int_t rc1 = 0, rc2 = 0, rc3 = 0;
598 if (pack && strlen(pack)) {
599 // remove package directory and par file
600 TString path = TString::Format("%s/downloaded/%s.par", fDir.Data(), pack);
601 gSystem->Exec(TString::Format("%s %s", kRM, path.Data()));
602 if (!gSystem->AccessPathName(path, kFileExists)) rc1 = -1;
603 path.ReplaceAll("/downloaded/", "/");
604 gSystem->Exec(TString::Format("%s %s", kRM, path.Data()));
605 if (!gSystem->AccessPathName(path, kFileExists)) rc2 = -1;
606 path.Remove(path.Last('.'));
607 gSystem->Exec(TString::Format("%s %s", kRM, path.Data()));
608 if (!gSystem->AccessPathName(path, kFileExists)) rc3 = -1;
609 } else {
610 // Clear all packages
611 rc1 = gSystem->Exec(TString::Format("%s %s/*", kRM, fDir.Data()));
612 }
613 if (dolock) fLock.Unlock();
614 return (rc1 + rc2 + rc3);
615}
616
617////////////////////////////////////////////////////////////////////////////////
618/// Get list of available packages
619/// Returns a pointer to a TList object, transferring ownership to the caller
620
622{
623 TList *plist = new TList;
624 void *dir = gSystem->OpenDirectory(fDir);
625 if (dir) {
626 TString pac(gSystem->GetDirEntry(dir));
627 while (pac.Length() > 0) {
628 if (pac.EndsWith(".par")) {
629 pac.ReplaceAll(".par","");
630 plist->Add(new TObjString(pac.Data()));
631 }
632 pac = gSystem->GetDirEntry(dir);
633 }
634 }
636
637 return plist;
638}
639
640////////////////////////////////////////////////////////////////////////////////
641/// Get list of enabled packages
642/// Returns a pointer to a TList object, transferring ownership to the caller
643
645{
646 TList *epl = nullptr;
648 epl = new TList;
650 TObject *o = 0;
651 while ((o = nxp())) {
652 epl->Add(new TObjString(o->GetName()));
653 }
654 }
655 return epl;
656}
657
658////////////////////////////////////////////////////////////////////////////////
659/// Show enabled packages
660///
661
662void TPackMgr::ShowEnabled(const char *title)
663{
665 // Scan the list of global packages dirs
667 TPackMgr *pm = 0;
668 while ((pm = (TPackMgr *)nxpm())) {
669 pm->ShowEnabled(TString::Format("*** Global Package cache %s %s:%s ***\n",
670 pm->GetName(), gSystem->HostName(), pm->GetTitle()));
671 }
672 }
673
674 if (!fEnabledPackages || fEnabledPackages->GetSize() <= 0) return;
675
676 if (title && strlen(title) > 0)
677 printf("%s\n", title);
678 else
679 printf("*** Package enabled on %s ***\n", gSystem->HostName());
680 fflush(stdout);
681
683 while (TPair *pck = (TPair *) next()) {
684 printf("%s\n", pck->GetName());
685 }
686}
687
688////////////////////////////////////////////////////////////////////////////////
689/// Get MD5 checksum of the PAR file corresponding to given package
690/// Returns a pointer to a TMD5 object, transferring ownership to the caller
691
692TMD5 *TPackMgr::GetMD5(const char *pack)
693{
694 // Shared lock from here
696 // PAR file path
697 const char *fm = (strstr(pack, ".par")) ? "%s/%s" : "%s/%s.par";
698 TString parfile = TString::Format(fm, fDir.Data(), pack);
699
700 return TMD5::FileChecksum(parfile);
701}
702
703
704////////////////////////////////////////////////////////////////////////////////
705/// Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
706/// Returns a pointer to a TMD5 object, transferring ownership to the caller
707
708TMD5 *TPackMgr::ReadMD5(const char *pack)
709{
710 TString pn(pack);
711 if (pn.EndsWith(".par")) pn.Remove(pn.Last('.'));
712
713 TString md5f = TString::Format("%s/%s/PROOF-INF/md5.txt", fDir.Data(), pn.Data());
715 return TMD5::ReadChecksum(md5f);
716}
717
718
719////////////////////////////////////////////////////////////////////////////////
720/// Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
721/// Returns a pointer to a TMD5 object, transferring ownership to the caller
722
723Int_t TPackMgr::Unpack(const char *pack, TMD5 *sum)
724{
725 Int_t rc = 0;
726 TString fn(pack), pn(pack);
727 if (!fn.EndsWith(".par")) fn += ".par";
728 if (pn.EndsWith(".par")) pn.Remove(pn.Last('.'));
729
730 // Find gunzip...
731 char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP, kExecutePermission);
732 if (gunzip) {
733 // untar package
734 TString cmd;
735 cmd.Form(kUNTAR, gunzip, fDir.Data(), fn.Data(), fDir.Data());
736 rc = gSystem->Exec(cmd);
737 if (rc != 0)
738 Error("Unpack", "failure executing: %s (rc: %d)", cmd.Data(), rc);
739 delete [] gunzip;
740 } else {
741 Error("Unpack", "%s not found", kGUNZIP);
742 rc = -2;
743 }
744 // check that fDir/pack now exists
746 // par file did not unpack itself in the expected directory, failure
747 rc = -1;
748 Error("Unpack", "package %s did not unpack into %s", fn.Data(), pn.Data());
749 } else {
750 // store md5 in package/PROOF-INF/md5.txt
751 if (sum) {
752 TString md5f = TString::Format("%s/%s/PROOF-INF/md5.txt", fDir.Data(), pn.Data());
754 }
755 }
756
757 return rc;
758}
759
760////////////////////////////////////////////////////////////////////////////////
761/// Install package from par (unpack the file in the directory); par can be an
762/// URL for remote retrieval. If rmold is kTRUE an existing version of the package
763/// is removed if existing.
764/// Returns 0 on success, <0 otherwise
765
766Int_t TPackMgr::Install(const char *parpath, Bool_t rmold)
767{
768 Int_t rc = 0;
769
770 Info("Install", "installing %s ...", parpath);
771 const char *par = gSystem->ExpandPathName(parpath);
772
773 // Does par exists?
775 Error("Install", "%s is invalid", par);
776 return -1;
777 }
778 TString parname = gSystem->BaseName(par);
779 TString pack = parname(0, parname.Last('.'));
780 TString dest = TString::Format("%s/%s", fDir.Data(), parname.Data());
781 TString psrc = par, ssrc;
782 TMD5 *sums = 0, *md5 = 0, *md5d = 0;
783
784 // Check if we need to download: get the remote checksum
785 // Retrieve the checksum of the file, if available
786 // Dowload checksum file, if available
787 TString dldir;
788 if (GetDownloadDir(dldir) != 0) {
789 Error("Install", "could not create/get download directory");
790 return -1;
791 }
792
794
795 TString parsum(par);
796 parsum.ReplaceAll(".par", ".md5sum");
797 if (!gSystem->AccessPathName(parsum, kReadPermission)) {
798 ssrc.Form("%s/%s", dldir.Data(), gSystem->BaseName(parsum));
799 if (!TFile::Cp(parsum, ssrc)) {
800 Warning("Install", "could not retrieve %s", parsum.Data());
801 } else {
802 md5 = TMD5::ReadChecksum(ssrc);
803 }
804 }
805
806 // Do we have already the file?
807 Bool_t parexists = (!gSystem->AccessPathName(dest)) ? kTRUE : kFALSE;
808
809 Bool_t install = kTRUE;
810 // If yes and we are asked to clean the old one, do it
811 if (parexists) {
812 install = kFALSE;
813 if (rmold) {
814 // Asked to remove: do it
815 if (Remove(pack, kFALSE) < 0) {
816 Error("Install", "could not remove existing version of '%s'", pack.Data());
817 if (md5) delete md5;
818 return -1;
819 }
820 install = kTRUE;
821 } else {
822 if (!md5) {
824 if (ft == TFile::kWeb || ft == TFile::kNet) {
825 psrc.Form("%s/%s", dldir.Data(), parname.Data());
826 if (!TFile::Cp(par, psrc)) {
827 Error("Install", "could not retrieve %s", par);
828 return -1;
829 }
830 }
831 // psrc is either the original par or the downloaded path
832 md5 = TMD5::FileChecksum(psrc);
833 }
834 // Now we need to compare with the local one
835 sums = TMD5::FileChecksum(dest);
836 if (sums && md5 && (*sums != *md5)) install = kTRUE;
837 }
838 }
839 if (sums) delete sums;
840
841 // Install if required
842 if (install) {
843 if (!TFile::Cp(psrc, dest)) {
844 Error("Install", "could not copy %s to %s", psrc.Data(), dest.Data());
845 if (md5) delete md5;
846 return -1;
847 }
848 }
849 md5d = TMD5::FileChecksum(dest);
850
851 if (md5 && *md5 != *md5d)
852 Warning("Install", "checksums do not match:\n\tdownloaded:\t%s\n\texpected:\t%s",
853 md5d->AsString(), md5->AsString());
854 if (Unpack(pack, md5d) != 0) {
855 Error("Install", "could not unpack %s", dest.Data());
856 rc = -1;
857 }
858 if (md5) delete md5;
859 if (md5d) delete md5d;
860 return rc;
861}
862
863//---------------------------------------------------------------------------------------------------
864// Static methods
865//---------------------------------------------------------------------------------------------------
866
867////////////////////////////////////////////////////////////////////////////////
868/// Parse one or more paths as possible sources of packages
869/// Returns number of paths added; or -1 in case of problems
870
872{
873 Int_t ng = 0;
874 // List of directories where to look for global packages
875 TString globpack(paths);
876 if (globpack.Length() > 0) {
877 Int_t from = 0;
878 TString ldir;
879 while (globpack.Tokenize(ldir, from, ":")) {
881 ::Warning("TPackMgr::RegisterGlobalPath",
882 "directory for global packages %s does not"
883 " exist or is not readable", ldir.Data());
884 } else {
885 // Add to the list, key will be "G<ng>", i.e. "G0", "G1", ...
886 TString key;
887 key.Form("G%d", ng++);
888 if (!fgGlobalPackMgrList) {
891 }
892 TPackMgr *pmgr = new TPackMgr(ldir);
893 pmgr->SetName(key);
895 ::Info("TPackMgr::RegisterGlobalPath",
896 "manager for global packages directory %s added to the list",
897 ldir.Data());
898 }
899 }
900 }
901 // Number of registered packages
902 return ng;
903}
904
905
906////////////////////////////////////////////////////////////////////////////////
907/// Get the package manager having 'pack'; priority is given to packmgr, if
908/// defined.
909/// Returns packmgr or nullptr
910
911TPackMgr *TPackMgr::GetPackMgr(const char *pack, TPackMgr *packmgr)
912{
913 if (packmgr && packmgr->Has(pack)) return packmgr;
914
916 // Scan the list of global packages managers
918 TPackMgr *pm = 0;
919 while ((pm = (TPackMgr *)nxpm())) {
920 if (pm->Has(pack)) return pm;
921 }
922 }
923 return nullptr;
924}
925
926
927////////////////////////////////////////////////////////////////////////////////
928/// Get the full path to PAR, looking also in the global dirs.
929/// Returns -1 if not found, 0 if available in global dirs, 1 if it can be
930/// uploaded from the local package dir.
931/// For the cases >= 0, par is filled with the path of the PAR file
932
933Int_t TPackMgr::FindParPath(TPackMgr *packmgr, const char *pack, TString &par)
934{
935 // Try the package dir
936 if (packmgr && packmgr->GetParPath(pack, par) == 0) return 1;
937
938 // Try global package dirs
940 // Scan the list of global packages dirs
942 TPackMgr *pm = 0;
943 while ((pm = (TPackMgr *)nxpm())) {
944 if (pm->GetParPath(pack, par) == 0) {
945 // Package found, stop searching
946 break;
947 }
948 par = "";
949 }
950 if (par.Length() > 0) return 0;
951 }
952 return -1;
953}
954
955////////////////////////////////////////////////////////////////////////////////
956/// Check if the package is enabled; priority is given to packmgr, if
957/// defined.
958/// Returns kTRUE if enabled
959
960Bool_t TPackMgr::IsEnabled(const char *pack, TPackMgr *packmgr)
961{
962 if (packmgr && packmgr->IsPackageEnabled(pack)) return kTRUE;
963
965 // Scan the list of global packages managers
967 TPackMgr *pm = 0;
968 while ((pm = (TPackMgr *)nxpm())) {
969 if (pm->IsPackageEnabled(pack)) return kTRUE;
970 }
971 }
972 // Not Enabled
973 return kFALSE;
974}
SVector< double, 2 > v
Definition: Dict.h:5
ROOT::R::TRInterface & r
Definition: Object.C:4
#define SafeDelete(p)
Definition: RConfig.hxx:543
#define f(i)
Definition: RSha256.hxx:104
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
#define gInterpreter
Definition: TInterpreter.h:553
static void DefaultLogger(const char *msg)
Definition: TPackMgr.cxx:42
const char *const kRM
Definition: TProof.h:142
const char *const kUNTAR
Definition: TProof.h:144
const char *const kUNTAR3
Definition: TProof.h:146
const char *const kGUNZIP
Definition: TProof.h:147
const char *const kLS
Definition: TProof.h:143
#define gROOT
Definition: TROOT.h:414
void Printf(const char *fmt,...)
@ kFileExists
Definition: TSystem.h:45
@ kExecutePermission
Definition: TSystem.h:46
@ kReadPermission
Definition: TSystem.h:48
@ kWritePermission
Definition: TSystem.h:47
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=0)
Resolve the file type as a function of the protocol field in 'name'.
Definition: TFile.cxx:4693
EFileType
File type.
Definition: TFile.h:187
@ kWeb
Definition: TFile.h:187
@ kNet
Definition: TFile.h:187
virtual Bool_t Cp(const char *dst, Bool_t progressbar=kTRUE, UInt_t buffersize=1000000)
Allows to copy this file to the dst URL.
Definition: TFile.cxx:4876
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:28
Int_t GetNargs() const
Number of function arguments.
Definition: TFunction.cxx:164
TList * GetListOfMethodArgs()
Return list containing the TMethodArgs of a TFunction.
Definition: TFunction.cxx:126
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:819
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:656
void SetName(const char *path)
Definition: TLockPath.h:36
Int_t Lock(Bool_t shared=kFALSE)
Definition: TLockPath.cxx:43
Int_t Unlock()
Unlock the directory.
Definition: TLockPath.cxx:80
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition: TMD5.cxx:474
static TMD5 * ReadChecksum(const char *file)
Returns checksum stored in ASCII in specified file.
Definition: TMD5.cxx:422
static Int_t WriteChecksum(const char *file, const TMD5 *md5)
Writes checksum in ASCII format to specified file.
Definition: TMD5.cxx:452
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:31
virtual Bool_t Load() const
Load the macro into the interpreter.
Definition: TMacro.cxx:247
virtual Int_t ReadFile(const char *filename)
Read lines in filename in this macro.
Definition: TMacro.cxx:336
TList * GetListOfLines() const
Definition: TMacro.h:51
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:301
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:31
Method or function calling interface.
Definition: TMethodCall.h:37
void ResetParam()
Reset parameter list. To be used before the first call the SetParam().
void Init(const TFunction *func)
Initialize the method invocation environment based on the TFunction object.
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
Definition: TMethodCall.h:64
void SetParam(Long_t l)
Add a long method parameter.
virtual ULong_t Hash() const
Return hash value for this object.
Definition: TNamed.h:49
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
Collectable string class.
Definition: TObjString.h:28
const char * GetName() const
Returns name of object.
Definition: TObjString.h:38
const TString & GetString() const
Definition: TObjString.h:46
void SetString(const char *s)
Definition: TObjString.h:45
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
The PROOF package manager contains tools to manage packages.
Definition: TPackMgr.h:37
Bool_t IsInDir(const char *path)
Method to check if 'path' is in the managed directory Return kTRUE or kFALSE.
Definition: TPackMgr.cxx:478
void SetName(const char *name)
Set the name of the TNamed.
Definition: TPackMgr.h:62
@ kCheckROOT
Definition: TPackMgr.h:39
TString fDir
Definition: TPackMgr.h:44
void Show(const char *title=0)
Show available packages.
Definition: TPackMgr.cxx:548
void GetEnabledPackages(TString &packlist)
Method to get a semi-colon separated list with the names of the enabled packages.
Definition: TPackMgr.cxx:501
static Bool_t IsEnabled(const char *pack, TPackMgr *packmgr=nullptr)
Check if the package is enabled; priority is given to packmgr, if defined.
Definition: TPackMgr.cxx:960
Int_t GetPackDir(const char *pack, TString &pdir)
Method to get the path of the dir for package 'pack'.
Definition: TPackMgr.cxx:487
const char * GetName() const
Returns name of object.
Definition: TPackMgr.h:61
static THashList * fgGlobalPackMgrList
Definition: TPackMgr.h:49
Int_t Build(const char *pack, Int_t opt=TPackMgr::kCheckROOT)
Method to build a package.
Definition: TPackMgr.cxx:87
Int_t Install(const char *par, Bool_t rmold=kFALSE)
Install package from par (unpack the file in the directory); par can be an URL for remote retrieval.
Definition: TPackMgr.cxx:766
Int_t GetParPath(const char *pack, TString &path)
Method to get the path of the PAR file for package 'pack'.
Definition: TPackMgr.cxx:521
Int_t GetDownloadDir(TString &dldir)
Method to get the download dir; create if not existing Return -1 in case of error (not found; not cre...
Definition: TPackMgr.cxx:534
Bool_t Has(const char *pack)
Method to check if this package manager has package 'pack'.
Definition: TPackMgr.cxx:458
Int_t Unpack(const char *pack, TMD5 *sum=0)
Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
Definition: TPackMgr.cxx:723
TMD5 * GetMD5(const char *pack)
Get MD5 checksum of the PAR file corresponding to given package Returns a pointer to a TMD5 object,...
Definition: TPackMgr.cxx:692
void ShowEnabled(const char *title=0)
Show enabled packages.
Definition: TPackMgr.cxx:662
void Log(const char *msg)
Wrapper to notofuer / logger.
Definition: TPackMgr.cxx:73
TLockPath fLock
Definition: TPackMgr.h:45
static Int_t FindParPath(TPackMgr *packmgr, const char *pack, TString &par)
Get the full path to PAR, looking also in the global dirs.
Definition: TPackMgr.cxx:933
TList * GetList() const
Get list of available packages Returns a pointer to a TList object, transferring ownership to the cal...
Definition: TPackMgr.cxx:621
TPackMgr(const TPackMgr &)
Int_t Clean(const char *pack)
Clean dir for package 'pack' Return -1 in case of error, 0 otherwise.
Definition: TPackMgr.cxx:576
static Int_t RegisterGlobalPath(const char *paths)
Parse one or more paths as possible sources of packages Returns number of paths added; or -1 in case ...
Definition: TPackMgr.cxx:871
Bool_t IsPackageEnabled(const char *pack)
Definition: TPackMgr.h:82
Int_t Load(const char *pack, TList *optls=0)
Method to load a package taking an option list Return -1 on error, 0 otherwise.
Definition: TPackMgr.cxx:220
Int_t Unload(const char *pack)
Method to unload a package.
Definition: TPackMgr.cxx:411
TPackMgrLog_t fLogger
Definition: TPackMgr.h:42
TList * fEnabledPackages
Definition: TPackMgr.h:47
TList * GetListOfEnabled() const
Get list of enabled packages Returns a pointer to a TList object, transferring ownership to the calle...
Definition: TPackMgr.cxx:644
static TPackMgr * GetPackMgr(const char *pack, TPackMgr *packmgr=nullptr)
Get the package manager having 'pack'; priority is given to packmgr, if defined.
Definition: TPackMgr.cxx:911
TString fPfx
Definition: TPackMgr.h:46
Int_t Remove(const char *pack=0, Bool_t dolock=kTRUE)
Remove package 'pack' If 'pack' is null or empty all packages are cleared.
Definition: TPackMgr.cxx:593
virtual ~TPackMgr()
Destroy a TPackMgr instance.
Definition: TPackMgr.cxx:64
TMD5 * ReadMD5(const char *pack)
Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
Definition: TPackMgr.cxx:708
const char * GetTitle() const
Returns title of object.
Definition: TPackMgr.h:63
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:102
const char * GetName() const
Returns name of object.
Definition: TMap.h:116
Named parameter, streamable and storable.
Definition: TParameter.h:37
const AParamType & GetVal() const
Definition: TParameter.h:69
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:892
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
Bool_t IsNull() const
Definition: TString.h:402
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
virtual int Symlink(const char *from, const char *to)
Create a symbolic link from file1 to file2.
Definition: TSystem.cxx:1358
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1264
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:4064
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:852
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:843
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:716
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1652
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3894
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:913
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:662
virtual void SetIncludePath(const char *includePath)
IncludePath should contain the list of compiler flags to indicate where to find user defined header f...
Definition: TSystem.cxx:4099
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1286
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:860
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:869
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:941
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:312
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:878
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1536
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1371
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1472
static long int sum(long int i)
Definition: Factory.cxx:2258
#define dest(otri, vertexptr)
Definition: triangle.c:1040