# -*- 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 import logging import commands 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) self.log.info(time.strftime ('%c')) # 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.log.debug("get_options") 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 self.log.debug("make_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): self.log.debug("make_tempory_file") # 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.tempprefix = "/tmp/CMT" 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 () if self.tempprefix != '': os.makedirs (self.tempprefix) ################################################################################################## #-------------------------------- prepare_cmt_context -------------------------------------------# ################################################################################################## def prepare_cmt_context (self): # Prepare the CMT and package context self.log.debug("prepare_cmt_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 self.log.debug("prepare_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.log.debug("prepare_externals") 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 self.log.debug("prepare_temp") 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): self.log.debug("build_pacman") self.log.debug("%s %s %s %s %s %s", 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' self.log.info ('build_pacman> Create pacman file for external stuff %s', 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 self.log.debug ('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() self.log.debug ('close file') # 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 cmd = "`echo "+self.version+" | sed -e 's#'^"+self.package+"-'##'`" status, vv= commands.getstatusoutput(cmd) 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 [