Package entropy :: Package client :: Package interfaces :: Module trigger

Source Code for Module entropy.client.interfaces.trigger

  1  # -*- coding: utf-8 -*- 
  2  """ 
  3   
  4      @author: Fabio Erculiani <lxnay@sabayonlinux.org> 
  5      @contact: lxnay@sabayonlinux.org 
  6      @copyright: Fabio Erculiani 
  7      @license: GPL-2 
  8   
  9      B{Entropy Package Manager Client Package installation triggers Interface}. 
 10   
 11  """ 
 12   
 13  from __future__ import with_statement 
 14  import subprocess 
 15  import shutil 
 16  from entropy.client.interfaces.client import Client 
 17  from entropy.const import * 
 18  from entropy.exceptions import * 
 19  from entropy.output import * 
 20  from entropy.i18n import _ 
 21   
22 -class Trigger:
23 24 import entropy.tools as entropyTools
25 - def __init__(self, EquoInstance, phase, pkgdata, package_action = None):
26 27 if not isinstance(EquoInstance,Client): 28 mytxt = _("A valid Entropy Instance is needed") 29 raise IncorrectParameter("IncorrectParameter: %s" % (mytxt,)) 30 31 self.Entropy = EquoInstance 32 self.clientLog = self.Entropy.clientLog 33 self.validPhases = ("preinstall","postinstall","preremove","postremove") 34 self.pkgdata = pkgdata 35 self.prepared = False 36 self.triggers = [] 37 self._trigger_data = {} 38 self.package_action = package_action 39 40 # Portage/Gentoo specific 41 self.MODULEDB_DIR="/var/lib/module-rebuild/" 42 self.INITSERVICES_DIR="/var/lib/init.d/" 43 44 self.spm_support = True 45 try: 46 Spm = self.Entropy.Spm() 47 self.Spm = Spm 48 except Exception, e: 49 self.entropyTools.print_traceback() 50 mytxt = darkred("%s, %s: %s, %s !") % ( 51 _("Source Package Manager interface can't be loaded"), 52 _("Error"), 53 e, 54 _("please fix"), 55 ) 56 self.Entropy.updateProgress( 57 mytxt, 58 importance = 0, 59 header = bold(" !!! ") 60 ) 61 self.spm_support = False 62 63 self.phase = phase 64 # validate phase 65 self.phaseValidation()
66
67 - def phaseValidation(self):
68 if self.phase not in self.validPhases: 69 mytxt = "%s: %s" % (_("Valid phases"),self.validPhases,) 70 raise InvalidData("InvalidData: %s" % (mytxt,))
71
72 - def prepare(self):
73 func = getattr(self, self.phase) 74 self.triggers = func() 75 self.prepared = True 76 return len(self.triggers) > 0
77
78 - def run(self):
79 for trigger in self.triggers: 80 fname = 'trigger_%s' % (trigger,) 81 if not hasattr(self,fname): continue 82 getattr(self, fname)()
83
84 - def kill(self):
85 self.prepared = False 86 self._trigger_data.clear() 87 del self.triggers[:]
88
89 - def postinstall(self):
90 91 functions = [] 92 if self.spm_support: 93 while 1: 94 if self.pkgdata['spm_phases'] != None: 95 if etpConst['spm']['postinst_phase'] not \ 96 in self.pkgdata['spm_phases']: 97 break 98 functions.append('ebuild_postinstall') 99 break 100 101 # load linker paths 102 ldpaths = self.Entropy.entropyTools.collect_linker_paths() 103 for x in self.pkgdata['content']: 104 105 if x.startswith("/etc/conf.d") or x.startswith("/etc/init.d"): 106 c_items = self._trigger_data.setdefault('conftouch', set()) 107 c_items.add(x) 108 if "conftouch" not in functions: 109 functions.append('conftouch') 110 111 if "env_update" not in functions: 112 if x.startswith('/etc/env.d/'): 113 functions.append('env_update') 114 115 if "run_ldconfig" not in functions: 116 if (os.path.dirname(x) in ldpaths): 117 if x.find(".so") > -1: 118 functions.append('run_ldconfig') 119 120 if self.pkgdata['trigger']: 121 functions.append('call_ext_postinstall') 122 123 del ldpaths 124 return functions
125
126 - def preinstall(self):
127 128 functions = [] 129 130 # Portage phases 131 if self.spm_support: 132 while 1: 133 if self.pkgdata['spm_phases'] != None: 134 if etpConst['spm']['preinst_phase'] not \ 135 in self.pkgdata['spm_phases']: 136 break 137 functions.append('ebuild_preinstall') 138 break 139 140 if self.pkgdata['trigger']: 141 functions.append('call_ext_preinstall') 142 143 return functions
144
145 - def postremove(self):
146 147 functions = [] 148 149 # load linker paths 150 ldpaths = self.Entropy.entropyTools.collect_linker_paths() 151 152 for x in self.pkgdata['removecontent']: 153 154 # initdisable, env_update; run_ldconfig 155 if len(functions) == 3: 156 break # no need to go further 157 158 if "initdisable" not in functions: 159 if x.startswith('/etc/init.d/'): 160 c_item = self._trigger_data.setdefault('initdisable', set()) 161 c_item.add(x) 162 functions.append('initdisable') 163 164 if "env_update" not in functions: 165 if x.startswith('/etc/env.d/'): 166 functions.append('env_update') 167 168 if "run_ldconfig" not in functions: 169 if (os.path.dirname(x) in ldpaths): 170 if x.find(".so") > -1: 171 functions.append('run_ldconfig') 172 173 if self.pkgdata['trigger']: 174 functions.append('call_ext_postremove') 175 176 del ldpaths 177 return functions
178 179
180 - def preremove(self):
181 182 functions = [] 183 184 # Portage hook 185 if self.spm_support: 186 187 while 1: 188 if self.pkgdata['spm_phases'] != None: 189 if etpConst['spm']['prerm_phase'] not \ 190 in self.pkgdata['spm_phases']: 191 break 192 functions.append('ebuild_preremove') 193 break 194 195 # doing here because we need /var/db/pkg stuff 196 # in place and also because doesn't make any difference 197 while 1: 198 if self.pkgdata['spm_phases'] != None: 199 if etpConst['spm']['postrm_phase'] not \ 200 in self.pkgdata['spm_phases']: 201 break 202 functions.append('ebuild_postremove') 203 break 204 205 if self.pkgdata['trigger']: 206 functions.append('call_ext_preremove') 207 208 return functions
209 210
212 return self.trigger_call_ext_generic()
213
215 return self.trigger_call_ext_generic()
216
218 return self.trigger_call_ext_generic()
219
221 return self.trigger_call_ext_generic()
222
223 - def trigger_call_ext_generic(self):
224 try: 225 return self.do_trigger_call_ext_generic() 226 except Exception, e: 227 mykey = self.pkgdata['category']+"/"+self.pkgdata['name'] 228 tb = self.entropyTools.get_traceback() 229 self.Entropy.updateProgress(tb, importance = 0, type = "error") 230 self.Entropy.clientLog.write(tb) 231 self.Entropy.clientLog.log( 232 ETP_LOGPRI_INFO, 233 ETP_LOGLEVEL_NORMAL, 234 "[POST] ATTENTION Cannot run External trigger for "+mykey+"!! "+str(Exception)+": "+str(e) 235 ) 236 mytxt = "%s: %s %s. %s." % ( 237 bold(_("QA")), 238 brown(_("Cannot run External trigger for")), 239 bold(mykey), 240 brown(_("Please report it")), 241 ) 242 self.Entropy.updateProgress( 243 mytxt, 244 importance = 0, 245 header = red(" ## ") 246 ) 247 return 0
248
249 - class EntropyShSandbox:
250
251 - def __init__(self, Entropy):
252 self.Entropy = Entropy 253 import entropy.tools as entropyTools 254 self.entropyTools = entropyTools
255
256 - def __env_setup(self, stage, pkgdata):
257 258 # mandatory variables 259 category = pkgdata.get('category') 260 if isinstance(category,unicode): 261 category = category.encode('utf-8') 262 263 pn = pkgdata.get('name') 264 if isinstance(pn,unicode): 265 pn = pn.encode('utf-8') 266 267 pv = pkgdata.get('version') 268 if isinstance(pv,unicode): 269 pv = pv.encode('utf-8') 270 271 pr = self.entropyTools.dep_get_portage_revision(pv) 272 pvr = pv 273 if pr == "r0": pvr += "-%s" % (pr,) 274 275 pet = pkgdata.get('versiontag') 276 if isinstance(pet,unicode): 277 pet = pet.encode('utf-8') 278 279 per = pkgdata.get('revision') 280 if isinstance(per,unicode): 281 per = per.encode('utf-8') 282 283 etp_branch = pkgdata.get('branch') 284 if isinstance(etp_branch,unicode): 285 etp_branch = etp_branch.encode('utf-8') 286 287 slot = pkgdata.get('slot') 288 if isinstance(slot,unicode): 289 slot = slot.encode('utf-8') 290 291 pkgatom = pkgdata.get('atom') 292 pkgkey = self.entropyTools.dep_getkey(pkgatom) 293 pvrte = pkgatom[len(pkgkey)+1:] 294 if isinstance(pvrte,unicode): 295 pvrte = pvrte.encode('utf-8') 296 297 etpapi = pkgdata.get('etpapi') 298 if isinstance(etpapi,unicode): 299 etpapi = etpapi.encode('utf-8') 300 301 p = pkgatom 302 if isinstance(p,unicode): 303 p = p.encode('utf-8') 304 305 chost, cflags, cxxflags = pkgdata.get('chost'), \ 306 pkgdata.get('cflags'), pkgdata.get('cxxflags') 307 308 chost = pkgdata.get('etpapi') 309 if isinstance(chost,unicode): 310 chost = chost.encode('utf-8') 311 312 cflags = pkgdata.get('etpapi') 313 if isinstance(cflags,unicode): 314 cflags = cflags.encode('utf-8') 315 316 cxxflags = pkgdata.get('etpapi') 317 if isinstance(cxxflags,unicode): 318 cxxflags = cxxflags.encode('utf-8') 319 320 # Not mandatory variables 321 322 eclasses = ' '.join(pkgdata.get('eclasses',[])) 323 if isinstance(eclasses,unicode): 324 eclasses = eclasses.encode('utf-8') 325 326 unpackdir = pkgdata.get('unpackdir','') 327 if isinstance(unpackdir,unicode): 328 unpackdir = unpackdir.encode('utf-8') 329 330 imagedir = pkgdata.get('imagedir','') 331 if isinstance(imagedir,unicode): 332 imagedir = imagedir.encode('utf-8') 333 334 sb_dirs = [unpackdir,imagedir] 335 sb_write = ':'.join(sb_dirs) 336 337 myenv = { 338 "ETP_API": etpSys['api'], 339 "ETP_LOG": self.Entropy.clientLog.get_fpath(), 340 "ETP_STAGE": stage, # entropy trigger stage 341 "ETP_PHASE": self.__get_sh_stage(), # entropy trigger phase 342 "ETP_BRANCH": etp_branch, 343 "CATEGORY": category, # package category 344 "PN": pn, # package name 345 "PV": pv, # package version 346 "PR": pr, # package revision (portage) 347 "PVR": pvr, # package version+revision 348 "PVRTE": pvrte, # package version+revision+entropy tag+entropy rev 349 "PER": per, # package entropy revision 350 "PET": pet, # package entropy tag 351 "SLOT": slot, # package slot 352 "PAPI": etpapi, # package entropy api 353 "P": p, # complete package atom 354 "WORKDIR": unpackdir, # temporary package workdir 355 "B": unpackdir, # unpacked binary package directory? 356 "D": imagedir, # package unpack destination (before merging to live) 357 "ENTROPY_TMPDIR": etpConst['packagestmpdir'], # entropy temporary directory 358 "CFLAGS": cflags, # compile flags 359 "CXXFLAGS": cxxflags, # compile flags 360 "CHOST": chost, # *nix CHOST 361 "PORTAGE_ECLASSES": eclasses, # portage eclasses, " " separated 362 "ROOT": etpConst['systemroot'], 363 "SANDBOX_WRITE": sb_write, 364 } 365 sysenv = os.environ.copy() 366 sysenv.update(myenv) 367 return sysenv
368
369 - def __get_sh_stage(self, stage):
370 mydict = { 371 "preinstall": "pkg_preinst", 372 "postinstall": "pkg_postinst", 373 "preremove": "pkg_prerm", 374 "postremove": "pkg_postrm", 375 } 376 return mydict.get(stage)
377
378 - def run(self, stage, pkgdata, trigger_file):
379 env = self.__env_setup(stage, pkgdata) 380 p = subprocess.Popen([trigger_file, stage], 381 stdout = sys.stdout, stderr = sys.stderr, 382 env = env 383 ) 384 rc = p.wait() 385 if os.path.isfile(trigger_file): 386 os.remove(trigger_file) 387 return rc
388
389 - class EntropyPySandbox:
390
391 - def __init__(self, Entropy):
392 self.Entropy = Entropy
393
394 - def run(self, stage, pkgdata, trigger_file):
395 my_ext_status = 1 396 if os.path.isfile(trigger_file): 397 execfile(trigger_file) 398 if os.path.isfile(trigger_file): 399 os.remove(trigger_file) 400 return my_ext_status
401
403 404 # if mute, supress portage output 405 if etpUi['mute']: 406 oldsystderr = sys.stderr 407 oldsysstdout = sys.stdout 408 stdfile = open("/dev/null","w") 409 sys.stdout = stdfile 410 sys.stderr = stdfile 411 412 tg_pfx = "%s/trigger-" % (etpConst['entropyunpackdir'],) 413 while 1: 414 triggerfile = "%s%s" % (tg_pfx,self.Entropy.entropyTools.get_random_number(),) 415 if not os.path.isfile(triggerfile): break 416 417 triggerdir = os.path.dirname(triggerfile) 418 if not os.path.isdir(triggerdir): 419 os.makedirs(triggerdir) 420 421 f = open(triggerfile,"w") 422 chunk = 1024 423 start = 0 424 while 1: 425 buf = self.pkgdata['trigger'][start:] 426 if not buf: break 427 f.write(buf) 428 start += chunk 429 f.flush() 430 f.close() 431 432 # if mute, restore old stdout/stderr 433 if etpUi['mute']: 434 sys.stderr = oldsystderr 435 sys.stdout = oldsysstdout 436 stdfile.close() 437 438 f = open(triggerfile,"r") 439 interpreter = f.readline().strip() 440 f.close() 441 entropy_sh = etpConst['trigger_sh_interpreter'] 442 if interpreter == "#!%s" % (entropy_sh,): 443 os.chmod(triggerfile,0775) 444 my = self.EntropyShSandbox(self.Entropy) 445 else: 446 my = self.EntropyPySandbox(self.Entropy) 447 return my.run(self.phase, self.pkgdata, triggerfile)
448 449
450 - def trigger_conftouch(self):
451 452 self.Entropy.clientLog.log( 453 ETP_LOGPRI_INFO, 454 ETP_LOGLEVEL_NORMAL, 455 "[POST] Updating {conf.d,init.d} mtime..." 456 ) 457 mytxt = "%s ..." % (_("Updating {conf.d,init.d} mtime"),) 458 self.Entropy.updateProgress( 459 brown(mytxt), 460 importance = 0, 461 header = red(" ## ") 462 ) 463 464 for path in self._trigger_data['conftouch']: 465 466 path = etpConst['systemroot']+path 467 if not os.access(path, os.W_OK | os.F_OK): 468 continue 469 try: 470 f_item = open(path, "abw") 471 except (OSError, IOError,): 472 continue 473 f_item.flush() 474 f_item.close()
475
476 - def trigger_initdisable(self):
477 478 for item in self._trigger_data['initdisable']: 479 480 item = etpConst['systemroot'] + item 481 if not os.access(item, os.F_OK | os.W_OK): 482 continue 483 484 myroot = "/" 485 if etpConst['systemroot']: 486 myroot = etpConst['systemroot']+"/" 487 runlevels_dir = etpConst['systemroot']+"/etc/runlevels" 488 runlevels = [] 489 490 if os.path.isdir(runlevels_dir) and os.access(runlevels_dir,os.R_OK): 491 runlevels = [x for x in os.listdir(runlevels_dir) \ 492 if os.path.isdir(os.path.join(runlevels_dir, x)) \ 493 and os.path.isfile( 494 os.path.join(runlevels_dir, x, os.path.basename(item))) 495 ] 496 497 for runlevel in runlevels: 498 self.Entropy.clientLog.log( 499 ETP_LOGPRI_INFO, 500 ETP_LOGLEVEL_NORMAL, 501 "[POST] Removing boot service: %s, runlevel: %s" % ( 502 os.path.basename(item), runlevel,) 503 ) 504 mytxt = "%s: %s : %s" % ( 505 brown(_("Removing boot service")), 506 os.path.basename(item), 507 runlevel, 508 ) 509 self.Entropy.updateProgress( 510 mytxt, 511 importance = 0, 512 header = red(" ## ") 513 ) 514 cmd = 'ROOT="%s" rc-update del %s %s' % (myroot, 515 os.path.basename(item), runlevel) 516 subprocess.call(cmd, shell = True)
517
518 - def trigger_run_ldconfig(self):
519 if not etpConst['systemroot']: 520 myroot = "/" 521 else: 522 myroot = etpConst['systemroot']+"/" 523 self.Entropy.clientLog.log( 524 ETP_LOGPRI_INFO, 525 ETP_LOGLEVEL_NORMAL, 526 "[POST] Running ldconfig" 527 ) 528 mytxt = "%s %s" % (_("Regenerating"),"/etc/ld.so.cache",) 529 self.Entropy.updateProgress( 530 brown(mytxt), 531 importance = 0, 532 header = red(" ## ") 533 ) 534 subprocess.call("ldconfig -r %s &> /dev/null" % (myroot,), shell = True)
535
536 - def trigger_env_update(self):
537 538 self.Entropy.clientLog.log( 539 ETP_LOGPRI_INFO, 540 ETP_LOGLEVEL_NORMAL, 541 "[POST] Running env-update" 542 ) 543 if os.access(etpConst['systemroot']+"/usr/sbin/env-update",os.X_OK): 544 mytxt = "%s ..." % (_("Updating environment"),) 545 self.Entropy.updateProgress( 546 brown(mytxt), 547 importance = 0, 548 header = red(" ## ") 549 ) 550 if etpConst['systemroot']: 551 subprocess.call("echo 'env-update --no-ldconfig' | chroot %s &> /dev/null" % (etpConst['systemroot'],), shell = True) 552 else: 553 subprocess.call('env-update --no-ldconfig &> /dev/null', shell = True)
554
556 stdfile = open("/dev/null","w") 557 oldstderr = sys.stderr 558 oldstdout = sys.stdout 559 sys.stderr = stdfile 560 561 myebuild = None 562 if os.path.isdir(self.pkgdata['xpakdir']) and \ 563 os.access(self.pkgdata['xpakdir'], os.R_OK): 564 565 myebuild = [self.pkgdata['xpakdir']+"/"+x for x \ 566 in os.listdir(self.pkgdata['xpakdir']) if \ 567 x.endswith(etpConst['spm']['source_build_ext'])] 568 569 if myebuild: 570 myebuild = myebuild[0] 571 portage_atom = self.pkgdata['category'] + "/" + \ 572 self.pkgdata['name'] + "-" + self.pkgdata['version'] 573 self.Entropy.updateProgress( 574 "SPM: %s" % (brown(_("post-install phase")),), 575 importance = 0, 576 header = red(" ## ") 577 ) 578 try: 579 580 if not etpUi['debug']: 581 sys.stdout = stdfile 582 self.__ebuild_setup_phase(myebuild, portage_atom) 583 if not etpUi['debug']: 584 sys.stdout = oldstdout 585 586 rc = self.Spm.execute_package_phase(portage_atom, myebuild, 587 "postinstall", 588 work_dir = self.pkgdata['unpackdir'], 589 licenses_accepted = self.pkgdata['accept_license'] 590 ) 591 if rc == 1: 592 self.Entropy.clientLog.log( 593 ETP_LOGPRI_INFO, 594 ETP_LOGLEVEL_NORMAL, 595 "[POST] ATTENTION Cannot properly run Source Package Manager post-install (pkg_postinst()) trigger for " + \ 596 str(portage_atom) + ". Something bad happened." 597 ) 598 599 except Exception, e: 600 sys.stdout = oldstdout 601 self.entropyTools.print_traceback() 602 self.Entropy.clientLog.log( 603 ETP_LOGPRI_INFO, 604 ETP_LOGLEVEL_NORMAL, 605 "[POST] ATTENTION Cannot run Source Package Manager trigger for "+portage_atom+"!! "+str(Exception)+": "+str(e) 606 ) 607 mytxt = "%s: %s %s. %s. %s: %s" % ( 608 bold(_("QA")), 609 brown(_("Cannot run Source Package Manager trigger for")), 610 bold(str(portage_atom)), 611 brown(_("Please report it")), 612 bold(_("Attach this")), 613 darkred(etpConst['spmlogfile']), 614 ) 615 self.Entropy.updateProgress( 616 mytxt, 617 importance = 0, 618 header = red(" ## ") 619 ) 620 sys.stderr = oldstderr 621 sys.stdout = oldstdout 622 stdfile.close() 623 return 0
624
625 - def __ebuild_setup_phase(self, ebuild, portage_atom):
626 rc = 0 627 env_file = self.pkgdata['unpackdir']+"/portage/"+portage_atom+"/temp/environment" 628 if not os.access(env_file, os.R_OK | os.F_OK): 629 rc = self.Spm.execute_package_phase(portage_atom, ebuild, 630 "setup", 631 work_dir = self.pkgdata['unpackdir'], 632 licenses_accepted = self.pkgdata['accept_license'] 633 ) 634 if rc == 1: 635 self.Entropy.clientLog.log( 636 ETP_LOGPRI_INFO, 637 ETP_LOGLEVEL_NORMAL, 638 "[POST] ATTENTION Cannot properly run Source Package Manager pkg_setup()" 639 " phase for "+str(portage_atom)+". Something bad happened." 640 ) 641 return rc
642 643
645 stdfile = open("/dev/null","w") 646 oldstderr = sys.stderr 647 oldstdout = sys.stdout 648 sys.stderr = stdfile 649 650 myebuild = None 651 if os.path.isdir(self.pkgdata['xpakdir']) and \ 652 os.access(self.pkgdata['xpakdir'], os.R_OK): 653 654 myebuild = [self.pkgdata['xpakdir']+"/"+x for x in \ 655 os.listdir(self.pkgdata['xpakdir']) if \ 656 x.endswith(etpConst['spm']['source_build_ext'])] 657 658 if myebuild: 659 myebuild = myebuild[0] 660 portage_atom = self.pkgdata['category'] + "/" + \ 661 self.pkgdata['name'] + "-" + self.pkgdata['version'] 662 self.Entropy.updateProgress( 663 "SPM: %s" % (brown(_("pre-install phase")),), 664 importance = 0, 665 header = red(" ## ") 666 ) 667 try: 668 669 if not etpUi['debug']: 670 sys.stdout = stdfile 671 self.__ebuild_setup_phase(myebuild, portage_atom) 672 if not etpUi['debug']: 673 sys.stdout = oldstdout 674 675 rc = self.Spm.execute_package_phase(portage_atom, myebuild, 676 "preinstall", 677 work_dir = self.pkgdata['unpackdir'], 678 licenses_accepted = self.pkgdata['accept_license'] 679 ) 680 if rc == 1: 681 self.Entropy.clientLog.log( 682 ETP_LOGPRI_INFO, 683 ETP_LOGLEVEL_NORMAL, 684 "[PRE] ATTENTION Cannot properly run Source Package Manager pre-install (pkg_preinst()) trigger for " + \ 685 str(portage_atom)+". Something bad happened." 686 ) 687 except Exception, e: 688 sys.stdout = oldstdout 689 self.entropyTools.print_traceback() 690 self.Entropy.clientLog.log( 691 ETP_LOGPRI_INFO, 692 ETP_LOGLEVEL_NORMAL, 693 "[PRE] ATTENTION Cannot run Source Package Manager preinst trigger for "+portage_atom+"!! "+str(Exception)+": "+str(e) 694 ) 695 mytxt = "%s: %s %s. %s. %s: %s" % ( 696 bold(_("QA")), 697 brown(_("Cannot run Source Package Manager trigger for")), 698 bold(str(portage_atom)), 699 brown(_("Please report it")), 700 bold(_("Attach this")), 701 darkred(etpConst['spmlogfile']), 702 ) 703 self.Entropy.updateProgress( 704 mytxt, 705 importance = 0, 706 header = red(" ## ") 707 ) 708 sys.stderr = oldstderr 709 sys.stdout = oldstdout 710 stdfile.close() 711 return 0
712
713 - def trigger_ebuild_preremove(self):
714 stdfile = open("/dev/null","w") 715 oldstderr = sys.stderr 716 sys.stderr = stdfile 717 718 portage_atom = self.pkgdata['category'] + "/" + self.pkgdata['name'] + \ 719 "-" + self.pkgdata['version'] 720 721 myebuild = self.Spm.get_installed_package_build_script_path( 722 portage_atom) 723 724 self.myebuild_moved = None 725 if os.path.isfile(myebuild): 726 try: 727 myebuild = self._setup_remove_ebuild_environment(myebuild, portage_atom) 728 except EOFError, e: 729 sys.stderr = oldstderr 730 stdfile.close() 731 # stuff on system is broken, ignore it 732 self.Entropy.updateProgress( 733 darkred("!!! Ebuild: pkg_prerm() failed, EOFError: ")+str(e)+darkred(" - ignoring"), 734 importance = 1, 735 type = "warning", 736 header = red(" ## ") 737 ) 738 return 0 739 except ImportError, e: 740 sys.stderr = oldstderr 741 stdfile.close() 742 # stuff on system is broken, ignore it 743 self.Entropy.updateProgress( 744 darkred("!!! Ebuild: pkg_prerm() failed, ImportError: ")+str(e)+darkred(" - ignoring"), 745 importance = 1, 746 type = "warning", 747 header = red(" ## ") 748 ) 749 return 0 750 751 if os.path.isfile(myebuild): 752 753 self.Entropy.updateProgress( 754 "SPM: %s" % (brown(_("pre-remove phase")),), 755 importance = 0, 756 header = red(" ## ") 757 ) 758 try: 759 rc = self.Spm.execute_package_phase(portage_atom, myebuild, 760 "preremove", 761 work_dir = etpConst['entropyunpackdir']+"/"+portage_atom, 762 licenses_accepted = self.pkgdata['accept_license'] 763 ) 764 if rc == 1: 765 self.Entropy.clientLog.log( 766 ETP_LOGPRI_INFO, 767 ETP_LOGLEVEL_NORMAL, 768 "[PRE] ATTENTION Cannot properly run Source Package Manager trigger for " + \ 769 str(portage_atom)+". Something bad happened." 770 ) 771 except Exception, e: 772 sys.stderr = oldstderr 773 stdfile.close() 774 self.entropyTools.print_traceback() 775 self.Entropy.clientLog.log( 776 ETP_LOGPRI_INFO, 777 ETP_LOGLEVEL_NORMAL, 778 "[PRE] ATTENTION Cannot run Source Package Manager " + \ 779 "pre-remove trigger for " + portage_atom + "!! " + \ 780 str(Exception)+": "+str(e) 781 ) 782 mytxt = "%s: %s %s. %s. %s: %s" % ( 783 bold(_("QA")), 784 brown(_("Cannot run Source Package Manager trigger for")), 785 bold(str(portage_atom)), 786 brown(_("Please report it")), 787 bold(_("Attach this")), 788 darkred(etpConst['spmlogfile']), 789 ) 790 self.Entropy.updateProgress( 791 mytxt, 792 importance = 0, 793 header = red(" ## ") 794 ) 795 return 0 796 797 sys.stderr = oldstderr 798 stdfile.close() 799 self._remove_overlayed_ebuild() 800 return 0
801
803 stdfile = open("/dev/null","w") 804 oldstderr = sys.stderr 805 sys.stderr = stdfile 806 807 portage_atom = self.pkgdata['category'] + "/" + self.pkgdata['name'] + \ 808 "-" + self.pkgdata['version'] 809 810 myebuild = self.Spm.get_installed_package_build_script_path( 811 portage_atom) 812 813 self.myebuild_moved = None 814 if os.path.isfile(myebuild): 815 try: 816 myebuild = self._setup_remove_ebuild_environment(myebuild, portage_atom) 817 except EOFError, e: 818 sys.stderr = oldstderr 819 stdfile.close() 820 # stuff on system is broken, ignore it 821 self.Entropy.updateProgress( 822 darkred("!!! Ebuild: pkg_postrm() failed, EOFError: ")+str(e)+darkred(" - ignoring"), 823 importance = 1, 824 type = "warning", 825 header = red(" ## ") 826 ) 827 return 0 828 except ImportError, e: 829 sys.stderr = oldstderr 830 stdfile.close() 831 # stuff on system is broken, ignore it 832 self.Entropy.updateProgress( 833 darkred("!!! Ebuild: pkg_postrm() failed, ImportError: ")+str(e)+darkred(" - ignoring"), 834 importance = 1, 835 type = "warning", 836 header = red(" ## ") 837 ) 838 return 0 839 840 if os.path.isfile(myebuild): 841 self.Entropy.updateProgress( 842 "SPM: %s" % (brown(_("post-remove phase")),), 843 importance = 0, 844 header = red(" ## ") 845 ) 846 try: 847 rc = self.Spm.execute_package_phase(portage_atom, myebuild, 848 "postremove", 849 work_dir = etpConst['entropyunpackdir']+"/"+portage_atom, 850 licenses_accepted = self.pkgdata['accept_license'] 851 ) 852 if rc == 1: 853 self.Entropy.clientLog.log( 854 ETP_LOGPRI_INFO, 855 ETP_LOGLEVEL_NORMAL, 856 "[PRE] ATTENTION Cannot properly run Source Package Manager postremove trigger for " + \ 857 str(portage_atom)+". Something bad happened." 858 ) 859 except Exception, e: 860 sys.stderr = oldstderr 861 stdfile.close() 862 self.entropyTools.print_traceback() 863 self.Entropy.clientLog.log( 864 ETP_LOGPRI_INFO, 865 ETP_LOGLEVEL_NORMAL, 866 "[PRE] ATTENTION Cannot run Source Package Manager postremove trigger for " + \ 867 portage_atom+"!! "+str(Exception)+": "+str(e) 868 ) 869 mytxt = "%s: %s %s. %s. %s: %s" % ( 870 bold(_("QA")), 871 brown(_("Cannot run Source Package Manager trigger for")), 872 bold(str(portage_atom)), 873 brown(_("Please report it")), 874 bold(_("Attach this")), 875 darkred(etpConst['spmlogfile']), 876 ) 877 self.Entropy.updateProgress( 878 mytxt, 879 importance = 0, 880 header = red(" ## ") 881 ) 882 return 0 883 884 sys.stderr = oldstderr 885 stdfile.close() 886 self._remove_overlayed_ebuild() 887 return 0
888
889 - def _setup_remove_ebuild_environment(self, myebuild, portage_atom):
890 891 ebuild_dir = os.path.dirname(myebuild) 892 ebuild_file = os.path.basename(myebuild) 893 894 # copy the whole directory in a safe place 895 dest_dir = os.path.join(etpConst['entropyunpackdir'],"vardb/"+portage_atom) 896 if os.path.exists(dest_dir): 897 if os.path.isdir(dest_dir): 898 shutil.rmtree(dest_dir,True) 899 elif os.path.isfile(dest_dir) or os.path.islink(dest_dir): 900 os.remove(dest_dir) 901 os.makedirs(dest_dir) 902 items = os.listdir(ebuild_dir) 903 for item in items: 904 myfrom = os.path.join(ebuild_dir,item) 905 myto = os.path.join(dest_dir,item) 906 shutil.copy2(myfrom,myto) 907 908 newmyebuild = os.path.join(dest_dir,ebuild_file) 909 if os.path.isfile(newmyebuild): 910 myebuild = newmyebuild 911 self.myebuild_moved = myebuild 912 self._ebuild_env_setup_hook(myebuild) 913 return myebuild
914
915 - def _ebuild_env_setup_hook(self, myebuild):
916 ebuild_path = os.path.dirname(myebuild) 917 if not etpConst['systemroot']: 918 myroot = "/" 919 else: 920 myroot = etpConst['systemroot']+"/" 921 922 # we need to fix ROOT= if it's set inside environment 923 bz2envfile = os.path.join(ebuild_path,"environment.bz2") 924 if os.path.isfile(bz2envfile) and os.path.isdir(myroot): 925 import bz2 926 envfile = self.Entropy.entropyTools.unpack_bzip2(bz2envfile) 927 bzf = bz2.BZ2File(bz2envfile,"w") 928 f = open(envfile,"r") 929 line = f.readline() 930 while line: 931 if line.startswith("ROOT="): 932 line = "ROOT=%s\n" % (myroot,) 933 bzf.write(line) 934 line = f.readline() 935 f.close() 936 bzf.close() 937 os.remove(envfile)
938
939 - def _remove_overlayed_ebuild(self):
940 if not self.myebuild_moved: 941 return 942 943 if os.path.isfile(self.myebuild_moved): 944 mydir = os.path.dirname(self.myebuild_moved) 945 shutil.rmtree(mydir,True) 946 mydir = os.path.dirname(mydir) 947 content = os.listdir(mydir) 948 while not content: 949 os.rmdir(mydir) 950 mydir = os.path.dirname(mydir) 951 content = os.listdir(mydir)
952