# config.py vi:ts=4:sw=4:expandtab: # # Copyright (c) 2006 Three Rings Design, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the copyright owner nor the names of contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. import os, ZConfig import builder def releases_handler(section): """ Validate a group of defined releases. Instantiate corresponding ReleaseBuilder objects. """ tags = [] releases = [] # Global tftproot section.tftproot = os.path.join(section.installroot, 'tftproot') # Validate release sections and instantiate # ReleaseBuilders. for release in section.Release: if (tags.count(release.cvstag) > 0): raise ZConfig.ConfigurationError("CVS Tags may not be re-used in mutiple Release sections. (Tag: \"%s\")" % (release.cvstag)) else: tags.append(release.cvstag) if (not release.binaryrelease and (release.cvsroot == None or release.cvstag == None)): raise ZConfig.ConfigurationError("You must either set BinaryRelease to True or set CVSRoot and CVSTag") if (release.binaryrelease and (release.iso == None)): raise ZConfig.ConfigurationError("ISO must be set if using a BinaryRelease") if (not release.useportsnap and release.cvsroot == None): raise ZConfig.ConfigurationError("UsePortsnap must be true or CVSRoot needs to be set") # The buildroot directory is merely a combination of the buildroot + release name release.buildroot = os.path.join(section.buildroot, release.getSectionName()) # And the chroots release.releaseroot = os.path.join(release.buildroot, 'releaseroot') release.pkgroot = os.path.join(release.buildroot, 'pkgroot') # And the ports tree release.portsdir = os.path.join(release.pkgroot, 'usr', 'ports') # And the package dir ... release.packagedir = os.path.join(release.portsdir, 'packages') return section def release_handler(section): # Add an NULL packages attribute section.packages = None return section def partition_handler(section): """ Validate a partition map, performing appropriate datatype conversions where necessary. """ # Validate known file systems if (section.type != 'ufs'): if (section.softupdates): # Only UFS supports softupdates. We'll fix this foible section.softupdates = False # If no mount point is specified, set string to "none" if (not section.mount): section.mount = 'none' # Convert bytes to 512 byte blocks section.size = section.size / 512 return section def package_handler(section): """ Provide a reasonable default for the package name """ if (not section.package): section.package = os.path.basename(section.port) return section def verifyReferences(config): """ Verify referential integrity between sections """ for inst in config.Installations.Installation: # Verify that Disk's defined PartitionMaps exist for disk in inst.Disk: foundPartitionMap = False for map in config.Partitions.PartitionMap: if (disk.partitionmap.lower() == map.getSectionName()): foundPartitionMap = True break if (not foundPartitionMap): raise ZConfig.ConfigurationError, "Can't find partition map \"%s\" for disk \"%s\" in \"%s\" installation." % (disk.partitionmap, disk.getSectionName(), inst.getSectionName()) # Verify that Installation's defined PackageSets exist for pkgsetName in inst.packageset: foundPackageSet = False for pkgset in config.PackageSets.PackageSet: if (pkgsetName.lower() == pkgset.getSectionName()): foundPackageSet = True break if (not foundPackageSet): raise ZConfig.ConfigurationError, "Can't find package set \"%s\" for \"%s\" installation." % (pkgsetName, inst.getSectionName()) def verifyPackages(config): """ Verify a given installation has only unique packages defined for each release. Build a list of packages to be built for each release. @param config: ZConfig object containing farb configuration """ # dictionary mapping packagesets to releases release_packagesets = {} # dictionary mapping packages to release release_packages = {} # Iterate over installations, finding all referenced package sets, # and associating them with releases. for install in config.Installations.Installation: releaseName = install.release.lower() if (not release_packagesets.has_key(releaseName)): release_packagesets[releaseName] = [] # Add all package sets for pkgsetName in install.packageset: for pkgset in config.PackageSets.PackageSet: if (pkgsetName.lower() == pkgset.getSectionName()): # Don't add the same packge set twice if (not release_packagesets[releaseName].count(pkgset)): release_packagesets[releaseName].append(pkgset) # Verify that packages only appear *once* in the list of packagesets # used in a specified release. for releaseName, packageSets in release_packagesets.iteritems(): if (not release_packages.has_key(releaseName)): release_packages[releaseName] = [] for packageSet in packageSets: for pkg in packageSet.Package: # If if this package has already been listed # by another packageset, in another installation, # using the same release, throw an error if (_hasPackage(release_packages, releaseName, pkg)): raise ZConfig.ConfigurationError("Packages may not be listed in more than one package set within the same release. (Port: \"%s\", Package Set: \"%s\", Release: \"%s\")" % (pkg.port, pkgsetName, install.release)) else: release_packages[releaseName].append(pkg) # Now add the package lists to the releases for release in config.Releases.Release: releaseName = release.getSectionName() # Do any installations reference this release? if (release_packages.has_key(releaseName)): # Don't add an empty list, leave release.packages set to None if (len(release_packages[releaseName])): release.packages = release_packages[releaseName] def _hasPackage(release_packages, releaseName, newpkg): """ Determine if a given package has already been added to the packages dictionary for a specified release. """ for pkg in release_packages[releaseName]: if (pkg.port == newpkg.port): return True return False