# -*- coding: iso-8859-1 -*- ######################################## # author: Garonne Vincent # # mail: garonne@lal.in2p3.fr # # Description: Class and methods to # # build a kit # # sources. # # Date: june/29/2005 # # based on the christian shell and # # python script # ######################################## import os import sys import string import popen2 import stat import re import time from os import path import getopt import tempfile import signal import tarfile from cmt import * class Kit: ################################################################################################## #--------------------------- __init__ -----------------------------------------------------------# ################################################################################################## def __init__ (self, DEBUG=False): # Log creation self.debug = DEBUG if DEBUG: self.log = logging.Logger(name='kit.py', level=logging.DEBUG) else: self.log = logging.Logger(name='kit.py', level=logging.INFO) hdlr = logging.StreamHandler() fmt = logging.Formatter("%(levelname)s:%(filename)s:%(lineno)d:%(message)s") hdlr.setFormatter(fmt) self.log.addHandler(hdlr) # Default options self.here = os.getcwd() self.kits_dir = self.here +'/kits' self.cache_dir = self.here +'/cache' self.rpm = False self.minimal = False self.pacman_only = False self.override = False self.do_source_kit = False self.patch_dir = '' self.patch_requirements = '' self.platform = '' self.platform_suffix = '' self.tempprefix = '' self.tempfile1 = '' self.tempfile2 = '' self.tempcopydir = '' self.tempcmtusercontext = '' self.patch_requirements = '' self.release = '' self.cyclefile = '' self.url = '' self.pacman_base = '' # CMT setup self.cmt = CMT () self.cmtversion = self.cmt.do ('version') self.log.info("cmtversion=%s", self.cmtversion) ################################################################################################## #----------------------------- get_options ------------------------------------------------------# ################################################################################################## def get_options (self, args): self.racine = os.path.dirname(os.path.realpath(args[0])) try: opts, args = getopt.getopt (args[1:] , 'r:c:P:mOp:osu:', ['release=' , 'cycles=' , 'patches=', 'minimal' , 'pacman_only' , 'platform=', 'override' , 'source' , 'url=']) except getopt.GetoptError: # print help information and exit: self.usage() sys.exit(2) for o,a in opts: if o in ('-r', '--release'): self.release = a if o in ('-c', '--cycles'): self.cyclefile = a if o in ('-P', '--patches'): self.patch_dir = a if o in ('-m', '--minimal'): self.minimal = True if o in ('-O', '--pacman_only'): self.pacman_only = True if o in ('-p', '--platform'): self.platform = a if o in ('-o', '--override'): self.override = True if o in ('-s', '--source'): self.do_source_kit = True if o in ('-u', '--url'): self.url = a for a in args: self.pacman_base = os.path.normpath (a) self.cache_dir = os.path.join (self.pacman_base, os.path.normpath ('cache')) self.kits_dir = os.path.join (self.pacman_base, os.path.normpath ('kits')) ################################################################################################## #----------------------------- make_pacman_cache ------------------------------------------------# ################################################################################################## def make_pacman_cache (self): # Prepare the target pacman cache if not os.path.isdir (self.cache_dir): self.log.info('Creating %s', self.cache_dir) os.makedirs (self.cache_dir) if not os.path.isdir (self.kits_dir): self.log.info('Creating %s', self.kits_dir) os.makedirs (self.kits_dir) ################################################################################################## #------------------------------------ make_tempory_file -----------------------------------------# ################################################################################################## def make_tempory_file (self): # associate handler #signal.signal(signal.SIG_DFL, self.cleanup); # 0 #signal.signal(signal.SIG_IGN, self.cleanup); # 1 signal.signal(signal.SIGINT, self.cleanup); # 2 signal.signal(signal.SIGTERM, self.cleanup); # 15 # Prepare temporary file management self.log.debug('CMT %s', str(os.getpid ())) self.log.debug('temprefix=%s', self.tempprefix) self.tempfile1 = os.path.join (self.tempprefix, 't') self.tempfile2 = os.path.join (self.tempprefix, 'u') self.tempcopydir = os.path.join (self.tempprefix, 'c') self.tempcmtusercontext = os.path.join (self.tempprefix, 'd') self.cleanup () os.makedirs (self.tempprefix) ################################################################################################## #-------------------------------- prepare_cmt_context -------------------------------------------# ################################################################################################## def prepare_cmt_context (self): # Prepare the CMT and package context h = self.cmt.do ('show pwd') root = os.path.dirname (h) self.cmtversion = self.cmt.do ('version') self.version = self.cmt.macro_value ('version') if self.version == 'v*': self.version = 'v1' self.log.debug('cmtversion=%s', self.cmtversion) self.log.debug('version=%s', self.version) self.package = self.cmt.macro_value ('package') self.__normpath(self.package) self.cmtpath = self.cmt.macro_value (self.package + '_cmtpath') self.__normpath (self.cmtpath) self.offset = self.cmt.macro_value (self.package + '_offset') self.__normpath (self.offset) self.log.debug('package=%s', self.package) self.log.debug('cmtpath=%s', self.cmtpath) self.log.debug('offset=%s', self.offset) self.project = self.cmt.macro_value (self.package + '_project') self.log.debug('package_project=%s', self.project) self.project_id = os.path.basename (self.project) self.log.debug('project_id=%s', self.project_id) self.release = self.cmt.macro_value (self.package + '_project_release') self.log.debug('package_project_release=%s', self.release) self.log.debug('CMTPATH=%s', self.cmt.macro_value ('CMTPATH')) if self.cmtpath == '': self.cmtpath = os.path.normpath (self.cmt.macro_value (self.package + '_root')) self.cmtpath = os.path.dirname (self.cmtpath) self.cmtpath = os.path.dirname (self.cmtpath) self.log.info('# Working on %s %s %s in %s project %s % s',\ self.package, self.version, self.offset, \ self.cmtpath, self.project, self.release) self.cleanup () ################################################################################################## #----------------------- prepare_patch_structure ------------------------------------------------# ################################################################################################## def prepare_patch_structure (self): # Prepare the patch structure if self.patch_dir != '': if os.path.isdir (os.path.join (self.patch_dir, self.project_id)): self.log.info("create_kit> %s/%s", self.patch_dir, self.project_id) os.makedirs (self.tempcmtusercontext) os.putenv ('CMTUSERCONTEXT', self.tempcmtusercontext) self.patch_requirements = os.path.join (self.tempcmtusercontext, \ os.path.normpath ('requirements')) files = list () files.append (os.path.join (self.patch_dir, self.project_id)+'/requirements') files.append (os.path.join (self.patch_dir, self.project_id)+self.package + \ '/requirements') # concatenate files outfile = open(self.patch_requirements, 'w+') for file in files: if os.path.isfile(file): file=open(file,'r') data=file.read() file.close() outfile.write(data) outfile.close() ################################################################################################## #--------------------------------- prepare_externals --------------------------------------------# ################################################################################################## def prepare_externals (self): # Prepare the detection of external packages self.native_version = self.cmt.macro_value (self.package + '_native_version') self.export_paths = self.cmt.macro_value (self.package + '_export_paths') self.is_internal = self.export_paths == None if self.do_source_kit: self.is_internal = True ################################################################################################## #------------------------------------------ prepare_temp ----------------------------------------# ################################################################################################## def prepare_temp (self): # Prepare the temporary copies os.makedirs (self.tempcopydir) copycmd = 'ln -s' if self.do_source_kit: self.acquire_sources() ################################################################################################## #------------------------------------------------------------------------------------------------# ################################################################################################## def generate_pacman(self): # Generate the pacman file self.build_pacman () ################################################################################################## #--------------------------------------- build_pacman -------------------------------------------# ################################################################################################## def build_pacman (self): print self.url, self.package, self.version, self.cmtpath, self.project_id, self.is_internal self.source = '../kits' # External packages (those with export_paths) are split into two kits: # o The internal part, which follows the naming convention for internal packages # o The external part, which only refers to the package version (no mention of # the project) # Naming cnvention: # external packages : -- # internal packages : /- if not self.is_internal: # first build the pacman file for the external stuff if self.native_version == None: cmd = "echo "+self.version+" | sed -e 's#'^"+self.package+"-'##'" status, vv = os.getstatusoutput(cmd) else: vv = self.native_version self.download_filename="${package}-${vv}${platform_suffix}" self.download_filename = self.package + '-' + vv + self.platform_suffix self.pacman_filename = self.download_filename + '.pacman' print 'build_pacman> Create pacman file for external stuff ' + self.pacman_filename file = os.path.join (self.cache_dir, self.pacman_filename) self.pacman_file_version = self.get_pacman_file_version (file) if os.path.isfile(file): os.rename(file, file + ".bak") # if test ! $? = 0; then # print 'create_kit> failed to rename ' + cache_dir + '/' + pacman_filename + ' to ' + cache_dir + '/' + pacman_filename' + '.bak' #sys.exit(2) # write pacman file f = open (file, 'w+') content = ''' description ('External Package %s %s %s %s') source = '%s' download = { '*':'%s.tar.gz' } '''%(self.package, self.version, self.platform, file, self.source, self.download_filename) f.write (content) f.close() # Figure out dependencies from CMT. # Only take directly used packages, not those used indirectly; # let pacman handle the cascade. # Filter the requirements file patch if any to get the direct use statements. # The cmt show uses does NOT show the use statements obtained from the CMTUSERCONTEXT thus # they have to be added manually here. # cmd = ''' `(if test ! "%s" = ""; then grep use %s | sed -e 's/use /# use /'; fi; cmt show uses) | cat | awk -f %s/get_depends.awk`'''%(self.patch_requirements, self.patch_requirements, self.racine) status, self.depsv = commands.getstatusoutput(cmd) if os.path.isfile(self.cyclefile): self.new_depsv= self.filter_deps(self.depsv) if self.new_depsv == self.depsv: print "Filtered dependencies: " print "depsv", self.depsv print "new_depsv", self.new_depsv self.depsv=self.new_depsv if self.project_id == "": self.release_id=self.release vv=os.system("`echo "+self.version+" | sed -e 's#'^"+self.package+"-'##'`") else: self.release_id=self.project_id vv=self.project_id # Format the depend statement according to Pacman syntax if self.depsv == "": self.depends="" else: self.project_dep=os.system("`echo "+self.project+self.platform_suffix+" | sed -e 's#/#-#'`") if self.project_dep== "contrib-CMT"+self.platform_suffix: self.project_dep = "CMTCONFIG-"+self.cmtversion+self.platform_suffix self.depends="package ('"+str(self.project_dep)+"')" first=True for f in self.depsv: p=os.system ("`echo "+f+" | cut -d: -f1`") v=os.system ("`echo "+f+" | cut -d: -f2`") pp=os.system ("`echo "+f+" | cut -d: -f3 | sed -e 's#/$##'`") # end build_pacman ################################################################################################## #------------------------------- usage ----------------------------------------------------------# ################################################################################################## def usage (self): print "Make a distribution kit for a CMT package" print "Usage: create_kit.sh [