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

Source Code for Module entropy.client.interfaces.trigger

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