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 sys.stdout = stdfile 593 self.__ebuild_setup_phase(myebuild, portage_atom) 594 sys.stdout = oldstdout 595 596 rc = self.Spm.spm_doebuild( 597 myebuild, 598 mydo = "postinst", 599 tree = "bintree", 600 cpv = portage_atom, 601 portage_tmpdir = self.pkgdata['unpackdir'], 602 licenses = self.pkgdata['accept_license'] 603 ) 604 if rc == 1: 605 self.Entropy.clientLog.log( 606 ETP_LOGPRI_INFO, 607 ETP_LOGLEVEL_NORMAL, 608 "[POST] ATTENTION Cannot properly run Gentoo postinstall (pkg_postinst()) trigger for " + \ 609 str(portage_atom) + ". Something bad happened." 610 ) 611 612 except Exception, e: 613 sys.stdout = oldstdout 614 self.entropyTools.print_traceback() 615 self.Entropy.clientLog.log( 616 ETP_LOGPRI_INFO, 617 ETP_LOGLEVEL_NORMAL, 618 "[POST] ATTENTION Cannot run Portage trigger for "+portage_atom+"!! "+str(Exception)+": "+str(e) 619 ) 620 mytxt = "%s: %s %s. %s. %s: %s" % ( 621 bold(_("QA")), 622 brown(_("Cannot run Portage trigger for")), 623 bold(str(portage_atom)), 624 brown(_("Please report it")), 625 bold(_("Attach this")), 626 darkred(etpConst['spmlogfile']), 627 ) 628 self.Entropy.updateProgress( 629 mytxt, 630 importance = 0, 631 header = red(" ## ") 632 ) 633 sys.stderr = oldstderr 634 sys.stdout = oldstdout 635 stdfile.close() 636 return 0
637
638 - def __ebuild_setup_phase(self, ebuild, portage_atom):
639 rc = 0 640 env_file = self.pkgdata['unpackdir']+"/portage/"+portage_atom+"/temp/environment" 641 if not os.path.isfile(env_file): 642 # if environment is not yet created, we need to run pkg_setup() 643 rc = self.Spm.spm_doebuild( 644 ebuild, 645 mydo = "setup", 646 tree = "bintree", 647 cpv = portage_atom, 648 portage_tmpdir = self.pkgdata['unpackdir'], 649 licenses = self.pkgdata['accept_license'] 650 ) # create mysettings["T"]+"/environment" 651 if rc == 1: 652 self.Entropy.clientLog.log( 653 ETP_LOGPRI_INFO, 654 ETP_LOGLEVEL_NORMAL, 655 "[POST] ATTENTION Cannot properly run Portage pkg_setup()" 656 " phase for "+str(portage_atom)+". Something bad happened." 657 ) 658 return rc
659 660
662 stdfile = open("/dev/null","w") 663 oldstderr = sys.stderr 664 oldstdout = sys.stdout 665 sys.stderr = stdfile 666 667 myebuild = None 668 if os.path.isdir(self.pkgdata['xpakdir']) and \ 669 os.access(self.pkgdata['xpakdir'], os.R_OK): 670 671 myebuild = [self.pkgdata['xpakdir']+"/"+x for x in \ 672 os.listdir(self.pkgdata['xpakdir']) if \ 673 x.endswith(etpConst['spm']['source_build_ext'])] 674 675 if myebuild: 676 myebuild = myebuild[0] 677 portage_atom = self.pkgdata['category']+"/"+self.pkgdata['name']+"-"+self.pkgdata['version'] 678 self.Entropy.updateProgress( 679 brown(" Ebuild: pkg_preinst()"), 680 importance = 0, 681 header = red(" ##") 682 ) 683 try: 684 685 sys.stdout = stdfile 686 self.__ebuild_setup_phase(myebuild, portage_atom) 687 sys.stdout = oldstdout 688 689 rc = self.Spm.spm_doebuild( 690 myebuild, 691 mydo = "preinst", 692 tree = "bintree", 693 cpv = portage_atom, 694 portage_tmpdir = self.pkgdata['unpackdir'], 695 licenses = self.pkgdata['accept_license'] 696 ) 697 if rc == 1: 698 self.Entropy.clientLog.log( 699 ETP_LOGPRI_INFO, 700 ETP_LOGLEVEL_NORMAL, 701 "[PRE] ATTENTION Cannot properly run Gentoo preinstall (pkg_preinst()) trigger for " + \ 702 str(portage_atom)+". Something bad happened." 703 ) 704 except Exception, e: 705 sys.stdout = oldstdout 706 self.entropyTools.print_traceback() 707 self.Entropy.clientLog.log( 708 ETP_LOGPRI_INFO, 709 ETP_LOGLEVEL_NORMAL, 710 "[PRE] ATTENTION Cannot run Gentoo preinst trigger for "+portage_atom+"!! "+str(Exception)+": "+str(e) 711 ) 712 mytxt = "%s: %s %s. %s. %s: %s" % ( 713 bold(_("QA")), 714 brown(_("Cannot run Portage trigger for")), 715 bold(str(portage_atom)), 716 brown(_("Please report it")), 717 bold(_("Attach this")), 718 darkred(etpConst['spmlogfile']), 719 ) 720 self.Entropy.updateProgress( 721 mytxt, 722 importance = 0, 723 header = red(" ## ") 724 ) 725 sys.stderr = oldstderr 726 sys.stdout = oldstdout 727 stdfile.close() 728 return 0
729
730 - def trigger_ebuild_preremove(self):
731 stdfile = open("/dev/null","w") 732 oldstderr = sys.stderr 733 sys.stderr = stdfile 734 735 portage_atom = self.pkgdata['category']+"/"+self.pkgdata['name']+"-"+self.pkgdata['version'] 736 try: 737 myebuild = self.Spm.get_vdb_path()+portage_atom+"/"+self.pkgdata['name']+"-"+self.pkgdata['version']+etpConst['spm']['source_build_ext'] 738 except: 739 myebuild = '' 740 741 self.myebuild_moved = None 742 if os.path.isfile(myebuild): 743 try: 744 myebuild = self._setup_remove_ebuild_environment(myebuild, portage_atom) 745 except EOFError, e: 746 sys.stderr = oldstderr 747 stdfile.close() 748 # stuff on system is broken, ignore it 749 self.Entropy.updateProgress( 750 darkred("!!! Ebuild: pkg_prerm() failed, EOFError: ")+str(e)+darkred(" - ignoring"), 751 importance = 1, 752 type = "warning", 753 header = red(" ## ") 754 ) 755 return 0 756 except ImportError, e: 757 sys.stderr = oldstderr 758 stdfile.close() 759 # stuff on system is broken, ignore it 760 self.Entropy.updateProgress( 761 darkred("!!! Ebuild: pkg_prerm() failed, ImportError: ")+str(e)+darkred(" - ignoring"), 762 importance = 1, 763 type = "warning", 764 header = red(" ## ") 765 ) 766 return 0 767 768 if os.path.isfile(myebuild): 769 770 self.Entropy.updateProgress( 771 brown(" Ebuild: pkg_prerm()"), 772 importance = 0, 773 header = red(" ##") 774 ) 775 try: 776 rc = self.Spm.spm_doebuild( 777 myebuild, 778 mydo = "prerm", 779 tree = "bintree", 780 cpv = portage_atom, 781 portage_tmpdir = etpConst['entropyunpackdir'] + "/" + portage_atom 782 ) 783 if rc == 1: 784 self.Entropy.clientLog.log( 785 ETP_LOGPRI_INFO, 786 ETP_LOGLEVEL_NORMAL, 787 "[PRE] ATTENTION Cannot properly run Portage trigger for " + \ 788 str(portage_atom)+". Something bad happened." 789 ) 790 except Exception, e: 791 sys.stderr = oldstderr 792 stdfile.close() 793 self.entropyTools.print_traceback() 794 self.Entropy.clientLog.log( 795 ETP_LOGPRI_INFO, 796 ETP_LOGLEVEL_NORMAL, 797 "[PRE] ATTENTION Cannot run Portage preremove trigger for "+portage_atom+"!! "+str(Exception)+": "+str(e) 798 ) 799 mytxt = "%s: %s %s. %s. %s: %s" % ( 800 bold(_("QA")), 801 brown(_("Cannot run Portage trigger for")), 802 bold(str(portage_atom)), 803 brown(_("Please report it")), 804 bold(_("Attach this")), 805 darkred(etpConst['spmlogfile']), 806 ) 807 self.Entropy.updateProgress( 808 mytxt, 809 importance = 0, 810 header = red(" ## ") 811 ) 812 return 0 813 814 sys.stderr = oldstderr 815 stdfile.close() 816 self._remove_overlayed_ebuild() 817 return 0
818
820 stdfile = open("/dev/null","w") 821 oldstderr = sys.stderr 822 sys.stderr = stdfile 823 824 portage_atom = self.pkgdata['category']+"/"+self.pkgdata['name']+"-"+self.pkgdata['version'] 825 try: 826 myebuild = self.Spm.get_vdb_path()+portage_atom+"/"+self.pkgdata['name']+"-"+self.pkgdata['version']+etpConst['spm']['source_build_ext'] 827 except: 828 myebuild = '' 829 830 self.myebuild_moved = None 831 if os.path.isfile(myebuild): 832 try: 833 myebuild = self._setup_remove_ebuild_environment(myebuild, portage_atom) 834 except EOFError, e: 835 sys.stderr = oldstderr 836 stdfile.close() 837 # stuff on system is broken, ignore it 838 self.Entropy.updateProgress( 839 darkred("!!! Ebuild: pkg_postrm() failed, EOFError: ")+str(e)+darkred(" - ignoring"), 840 importance = 1, 841 type = "warning", 842 header = red(" ## ") 843 ) 844 return 0 845 except ImportError, e: 846 sys.stderr = oldstderr 847 stdfile.close() 848 # stuff on system is broken, ignore it 849 self.Entropy.updateProgress( 850 darkred("!!! Ebuild: pkg_postrm() failed, ImportError: ")+str(e)+darkred(" - ignoring"), 851 importance = 1, 852 type = "warning", 853 header = red(" ## ") 854 ) 855 return 0 856 857 if os.path.isfile(myebuild): 858 self.Entropy.updateProgress( 859 brown(" Ebuild: pkg_postrm()"), 860 importance = 0, 861 header = red(" ##") 862 ) 863 try: 864 rc = self.Spm.spm_doebuild( 865 myebuild, 866 mydo = "postrm", 867 tree = "bintree", 868 cpv = portage_atom, 869 portage_tmpdir = etpConst['entropyunpackdir']+"/"+portage_atom 870 ) 871 if rc == 1: 872 self.Entropy.clientLog.log( 873 ETP_LOGPRI_INFO, 874 ETP_LOGLEVEL_NORMAL, 875 "[PRE] ATTENTION Cannot properly run Gentoo postremove trigger for " + \ 876 str(portage_atom)+". Something bad happened." 877 ) 878 except Exception, e: 879 sys.stderr = oldstderr 880 stdfile.close() 881 self.entropyTools.print_traceback() 882 self.Entropy.clientLog.log( 883 ETP_LOGPRI_INFO, 884 ETP_LOGLEVEL_NORMAL, 885 "[PRE] ATTENTION Cannot run Gentoo postremove trigger for " + \ 886 portage_atom+"!! "+str(Exception)+": "+str(e) 887 ) 888 mytxt = "%s: %s %s. %s. %s: %s" % ( 889 bold(_("QA")), 890 brown(_("Cannot run Portage trigger for")), 891 bold(str(portage_atom)), 892 brown(_("Please report it")), 893 bold(_("Attach this")), 894 darkred(etpConst['spmlogfile']), 895 ) 896 self.Entropy.updateProgress( 897 mytxt, 898 importance = 0, 899 header = red(" ## ") 900 ) 901 return 0 902 903 sys.stderr = oldstderr 904 stdfile.close() 905 self._remove_overlayed_ebuild() 906 return 0
907
908 - def _setup_remove_ebuild_environment(self, myebuild, portage_atom):
909 910 ebuild_dir = os.path.dirname(myebuild) 911 ebuild_file = os.path.basename(myebuild) 912 913 # copy the whole directory in a safe place 914 dest_dir = os.path.join(etpConst['entropyunpackdir'],"vardb/"+portage_atom) 915 if os.path.exists(dest_dir): 916 if os.path.isdir(dest_dir): 917 shutil.rmtree(dest_dir,True) 918 elif os.path.isfile(dest_dir) or os.path.islink(dest_dir): 919 os.remove(dest_dir) 920 os.makedirs(dest_dir) 921 items = os.listdir(ebuild_dir) 922 for item in items: 923 myfrom = os.path.join(ebuild_dir,item) 924 myto = os.path.join(dest_dir,item) 925 shutil.copy2(myfrom,myto) 926 927 newmyebuild = os.path.join(dest_dir,ebuild_file) 928 if os.path.isfile(newmyebuild): 929 myebuild = newmyebuild 930 self.myebuild_moved = myebuild 931 self._ebuild_env_setup_hook(myebuild) 932 return myebuild
933
934 - def _ebuild_env_setup_hook(self, myebuild):
935 ebuild_path = os.path.dirname(myebuild) 936 if not etpConst['systemroot']: 937 myroot = "/" 938 else: 939 myroot = etpConst['systemroot']+"/" 940 941 # we need to fix ROOT= if it's set inside environment 942 bz2envfile = os.path.join(ebuild_path,"environment.bz2") 943 if os.path.isfile(bz2envfile) and os.path.isdir(myroot): 944 import bz2 945 envfile = self.Entropy.entropyTools.unpack_bzip2(bz2envfile) 946 bzf = bz2.BZ2File(bz2envfile,"w") 947 f = open(envfile,"r") 948 line = f.readline() 949 while line: 950 if line.startswith("ROOT="): 951 line = "ROOT=%s\n" % (myroot,) 952 bzf.write(line) 953 line = f.readline() 954 f.close() 955 bzf.close() 956 os.remove(envfile)
957
958 - def _remove_overlayed_ebuild(self):
959 if not self.myebuild_moved: 960 return 961 962 if os.path.isfile(self.myebuild_moved): 963 mydir = os.path.dirname(self.myebuild_moved) 964 shutil.rmtree(mydir,True) 965 mydir = os.path.dirname(mydir) 966 content = os.listdir(mydir) 967 while not content: 968 os.rmdir(mydir) 969 mydir = os.path.dirname(mydir) 970 content = os.listdir(mydir)
971