# -*- mode:Python -*- # # This file is part of the Coriolis Software. # Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved # # +-----------------------------------------------------------------+ # | C O R I O L I S | # | T o o l c h a i n B u i l d e r | # | | # | Author : Jean-Paul Chaput | # | E-mail : Jean-Paul.Chaput@lip6.fr | # | =============================================================== | # | Python : "./builder/Configuration.py" | # +-----------------------------------------------------------------+ import sys import re import os import os.path import datetime import subprocess from . import ErrorMessage from .Project import Project class Configuration ( object ): PrimaryNames = \ [ 'confFile' , 'projects', 'standalones' , 'gitHash' , 'gitMethod', 'revDate' , 'projectDir' , 'rootDir' , 'packageName', 'packageVersion', 'packageExcludes', 'packageProjects' , 'osType' , 'libSuffix', 'buildMode', 'libMode', 'enableShared' ] SecondaryNames = \ [ 'rpmbuildDir' , 'debbuildDir' , 'tmppathDir' , 'tarballDir' , 'archiveDir' , 'sourceDir' , 'osDir' , 'buildDir' , 'installDir' , 'bootstrapDir' , 'specFileIn' , 'specFile' , 'debianDir' , 'debChangelogIn', 'debChangelog', 'sourceTarBz2' , 'binaryTarBz2', 'distribPatch' ] def __init__ ( self ): self._confFile = None self._projects = [] self._standalones = [] self._revDate = datetime.date.today().strftime('%Y%m%d') self._gitHash = "x" self._gitMethod = None self._projectDir = 'coriolis-2.x' self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir ) self._packageName = None self._packageVersion = None self._packageExcludes = [] self._packageProject = [] self._enableShared = 'ON' self._buildMode = 'Release' # Secondary (derived) variables. # Setup by _updateSecondary(). self._guessOs() self._updateSecondary() return def __setattr__ ( self, attribute, value ): if attribute in Configuration.SecondaryNames: print( ErrorMessage( 1, 'Attempt to write in read-only attribute "{}" in Configuration.' \ .format(attribute) )) return if attribute[0] == '_': self.__dict__[attribute] = value return if attribute == 'rootDir': value = os.path.expanduser(value) elif attribute == 'enableShared' and value != 'ON': value = 'OFF' self.__dict__['_'+attribute] = value self._updateSecondary() return def __getattr__ ( self, attribute ): if attribute[0] != '_': attribute = '_'+attribute if not attribute in self.__dict__: raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute ) return self.__dict__[attribute] def _updateSecondary ( self ): if self._enableShared == "ON": self._libMode = "Shared" else: self._libMode = "Static" #self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir ) self._rpmbuildDir = os.path.join ( self._rootDir , "rpmbuild" ) self._debbuildDir = os.path.join ( self._rootDir , "debbuild" ) self._tmppathDir = os.path.join ( self._rpmbuildDir, "tmp" ) self._tarballDir = os.path.join ( self._rootDir , "tarball" ) self._archiveDir = os.path.join ( self._tarballDir , "%s-%s.%sgit%s" % (self._packageName ,self._packageVersion ,self._revDate ,self._gitHash) ) self._sourceDir = os.path.join ( self._rootDir , "src" ) self._bootstrapDir = os.path.join ( self._sourceDir , "coriolis/bootstrap" ) self._osDir = os.path.join ( self._rootDir , self._osType , "%s.%s" % (self._buildMode,self._libMode) ) self._buildDir = os.path.join ( self._osDir, "build" ) self._installDir = os.path.join ( self._osDir, "install" ) self._specFileIn = os.path.join ( self._bootstrapDir, "%s.spec.in"%self._packageName ) self._specFile = os.path.join ( self._bootstrapDir, "%s.spec" %self._packageName ) self._debianDir = os.path.join ( self._bootstrapDir, "debian" ) self._debChangelogIn = os.path.join ( self._debianDir , "changelog.in" ) self._debChangelog = os.path.join ( self._debianDir , "changelog" ) self._sourceTarBz2 = "%s-%s.%sgit%s.tar.bz2" % (self._packageName ,self._packageVersion ,self._revDate ,self._gitHash) self._binaryTarBz2 = "%s-binary-%s.%sgit%s-1.el7.tar.bz2" % (self._packageName ,self._packageVersion ,self._revDate ,self._gitHash) self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName ) return def _guessOs ( self ): self._libSuffix = None self._osEL9 = re.compile (".*Linux.*(el9|al9).*x86_64.*") self._osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*") self._osSlsoc6x_64 = re.compile (".*Linux.*(el6|slsoc6).*x86_64.*") self._osSlsoc6x = re.compile (".*Linux.*(el6|slsoc6).*") self._osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*") self._osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*") self._osFedora_64 = re.compile (".*Linux.*fc.*x86_64.*") self._osFedora = re.compile (".*Linux.*fc.*") self._osLinux_64 = re.compile (".*Linux.*x86_64.*") self._osLinux = re.compile (".*Linux.*") self._osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*") self._osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*") self._osFreeBSD8x = re.compile (".*FreeBSD 8.*") self._osDarwin = re.compile (".*Darwin.*") self._osCygwinW7_64 = re.compile (".*CYGWIN_NT-6\.1.*x86_64.*") self._osCygwinW7 = re.compile (".*CYGWIN_NT-6\.1.*i686.*") self._osCygwinW8_64 = re.compile (".*CYGWIN_NT-6\.[2-3].*x86_64.*") self._osCygwinW8 = re.compile (".*CYGWIN_NT-6\.[2-3].*i686.*") self._osCygwinW10_64 = re.compile (".*CYGWIN_NT-10\.[0-3].*x86_64.*") self._osCygwinW10 = re.compile (".*CYGWIN_NT-10\.[0-3].*i686.*") uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE ) lines = uname.stdout.readlines() osLine = lines[0].decode( 'ascii' ) if self._osEL9.match(osLine): self._osType = "Linux.el9" self._libSuffix = "64" elif self._osSlsoc7x_64.match(osLine): self._osType = "Linux.el7_64" self._libSuffix = "64" elif self._osSlsoc6x_64.match(osLine): self._osType = "Linux.slsoc6x_64" self._libSuffix = "64" elif self._osSlsoc6x .match(osLine): self._osType = "Linux.slsoc6x" elif self._osSLSoC5x_64.match(osLine): self._osType = "Linux.SLSoC5x_64" self._libSuffix = "64" elif self._osSLSoC5x .match(osLine): self._osType = "Linux.SLSoC5x" elif self._osFedora_64 .match(osLine): self._osType = "Linux.fc_64" self._libSuffix = "64" elif self._osFedora .match(osLine): self._osType = "Linux.fc" elif self._osLinux_64 .match(osLine): self._osType = "Linux.x86_64" if os.path.exists("/usr/lib64/"): self._libSuffix = "64" elif self._osLinux .match(osLine): self._osType = "Linux.i386" elif self._osDarwin .match(osLine): self._osType = "Darwin" elif self._osFreeBSD8x_amd64.match(osLine): self._osType = "FreeBSD.8x.amd64" self._libSuffix = "64" elif self._osFreeBSD8x_64.match(osLine): self._osType = "FreeBSD.8x.x86_64" self._libSuffix = "64" elif self._osFreeBSD8x .match(osLine): self._osType = "FreeBSD.8x.i386" elif self._osCygwinW7_64.match(osLine): self._osType = "Cygwin.W7_64" self._libSuffix = "64" elif self._osCygwinW7.match(osLine): self._osType = "Cygwin.W7" elif self._osCygwinW8_64.match(osLine): self._osType = "Cygwin.W8_64" self._libSuffix = "64" elif self._osCygwinW8.match(osLine): self._osType = "Cygwin.W8" elif self._osCygwinW10_64.match(osLine): self._osType = "Cygwin.W10_64" self._libSuffix = "64" elif self._osCygwinW10.match(osLine): self._osType = "Cygwin.W10" else: uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE ) self._osType = uname.stdout.readlines()[0][:-1] print( '[WARNING] Unrecognized OS: "{}."'.format(osLine[:-1]) ) print( ' (using: "{}")'.format(self._osType) ) if self._libSuffix == '64' and not os.path.exists('/usr/lib64'): self._libSuffix = None return def getPrimaryIds ( self ): return Configuration.PrimaryNames def getSecondaryIds ( self ): return Configuration.SecondaryNames def getAllIds ( self ): return Configuration.PrimaryNames + Configuration.SecondaryNames def register ( self, project ): for registered in self._projects: if registered.getName() == project.getName(): print( ErrorMessage( 0, 'Project "{}" is already registered (ignored).'.format(project.getName()) )) return self._projects += [ project ] return def getProject ( self, name ): for project in self._projects: if project.getName() == name: return project return None def getToolProject ( self, name ): for project in self._projects: if project.hasTool(name): return project return None def load ( self, confFile ): moduleGlobals = globals() if not confFile: print( 'Making an educated guess to locate the configuration file:' ) locations = [ os.path.abspath(os.path.dirname(sys.argv[0])) , os.environ['HOME']+'/coriolis-2.x/src/coriolis/bootstrap' , os.environ['HOME']+'/coriolis/src/coriolis/bootstrap' , '/users/outil/coriolis/coriolis-2.x/src/coriolis/bootstrap' , self._rootDir+'/src/coriolis/bootstrap' ] for location in locations: self._confFile = location + '/build.conf' print( ' "{}"'.format(self._confFile) ) if os.path.isfile(self._confFile): break if not self._confFile: ErrorMessage( 1, 'Cannot locate any configuration file.' ).terminate() else: print( 'Using user-supplied configuration file:' ) print( ' "{}"'.format(confFile) ) self._confFile = confFile if not os.path.isfile(self._confFile): ErrorMessage( 1, 'Missing configuration file:', '<%s>'%self._confFile ).terminate() print( 'Reading configuration from:' ) print( ' "{}"'.format(self._confFile) ) try: exec( open(self._confFile).read(), globals() ) except Exception as e: ErrorMessage( 1, 'An exception occured while loading the configuration file:' , '<%s>\n' % (self._confFile) , 'You should check for simple python errors in this file.' , 'Error was:' , '%s\n' % e ).terminate() if 'projects' in moduleGlobals: entryNb = 0 for entry in moduleGlobals['projects']: entryNb += 1 if not 'name' in entry: raise ErrorMessage( 1, 'Missing project name in project entry #%d.' % entryNb ) if not 'tools' in entry: raise ErrorMessage( 1, 'Missing tools list in project entry #%d (<%s>).' \ % (entryNb,entry['name']) ) if not isinstance(entry['tools'],list): raise ErrorMessage( 1, 'Tools item of project entry #%d (<%s>) is not a list.' \ % (entryNb,entry['name']) ) if not 'repository' in entry: raise ErrorMessage( 1, 'Missing project repository in project entry #%d.' \ % entryNb ) self.register( Project(entry['name'],entry['tools'],entry['repository']) ) else: ErrorMessage( 1, 'Configuration file is missing the "project" symbol.' , '"{}"'.format(self._confFile) ).terminate() if 'projectdir' in moduleGlobals: self.projectDir = moduleGlobals['projectdir'] if 'svnconfig' in moduleGlobals: svnconfig = moduleGlobals['svnconfig'] if 'method' in svnconfig: self._svnMethod = svnconfig['method'] if 'package' in moduleGlobals: package = moduleGlobals['package'] if 'name' in package: self.packageName = package['name'] if 'version' in package: self.packageVersion = package['version'] if 'excludes' in package: if not isinstance(package['excludes'],list): raise ErrorMessage( 1, 'Excludes of package configuration is not a list.') self._packageExcludes = package['excludes'] if 'projects' in package: if not isinstance(package['projects'],list): raise ErrorMessage( 1, 'Projects to package is not a list.') self._packageProjects = package['projects'] return def show ( self ): print( 'CCB Configuration:' ) if self._gitMethod: print( ' Git Method: "{}"'.format(self._gitMethod) ) else: print( ' Git Method not defined, will not be able to push/pull.' ) for project in self._projects: print( ' project:{0:>15} repository:"{1}"' \ .format( '"{}"'.format(project.getName()), project.getRepository() )) toolOrder = 1 for tool in project.getTools(): print( '{0}{1:02}:"{2}"'.format( ' '*26, toolOrder, tool )) toolOrder += 1 print return