setup.py revision 1506
409N/A#!/usr/bin/python2.4
290N/A#
290N/A# CDDL HEADER START
290N/A#
290N/A# The contents of this file are subject to the terms of the
290N/A# Common Development and Distribution License (the "License").
290N/A# You may not use this file except in compliance with the License.
290N/A#
290N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
290N/A# or http://www.opensolaris.org/os/licensing.
290N/A# See the License for the specific language governing permissions
290N/A# and limitations under the License.
290N/A#
290N/A# When distributing Covered Code, include this CDDL HEADER in each
290N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
290N/A# If applicable, add the following below this CDDL HEADER, with the
290N/A# fields enclosed by brackets "[]" replaced with your own identifying
290N/A# information: Portions Copyright [yyyy] [name of copyright owner]
290N/A#
290N/A# CDDL HEADER END
290N/A#
395N/A# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
395N/A# Use is subject to license terms.
395N/A#
290N/A
290N/Aimport errno
290N/Aimport fnmatch
290N/Aimport os
290N/Aimport platform
290N/Aimport stat
383N/Aimport sys
290N/Aimport shutil
395N/Aimport re
290N/Aimport subprocess
395N/Aimport tarfile
290N/Aimport tempfile
290N/Aimport urllib
290N/Aimport py_compile
290N/Aimport sha
290N/A
383N/Afrom distutils.errors import DistutilsError
290N/Afrom distutils.core import setup, Extension
290N/Afrom distutils.cmd import Command
290N/Afrom distutils.command.install import install as _install
290N/Afrom distutils.command.build import build as _build
290N/Afrom distutils.command.build_py import build_py as _build_py
290N/Afrom distutils.command.bdist import bdist as _bdist
290N/Afrom distutils.command.clean import clean as _clean
290N/A
290N/Afrom distutils.sysconfig import get_python_inc
290N/Aimport distutils.file_util as file_util
290N/Aimport distutils.dir_util as dir_util
290N/Aimport distutils.util as util
290N/A
395N/A# 3rd party software required for the build
395N/ACP = 'CherryPy'
290N/ACPIDIR = 'cherrypy'
395N/ACPVER = '3.1.1'
395N/ACPARC = '%s-%s.tar.gz' % (CP, CPVER)
290N/ACPDIR = '%s-%s' % (CP, CPVER)
395N/ACPURL = 'http://download.cherrypy.org/cherrypy/%s/%s' % (CPVER, CPARC)
395N/ACPHASH = '0a8aace00ea28adc05edd41e20dd910042e6d265'
290N/A
395N/APO = 'pyOpenSSL'
395N/APOIDIR = 'OpenSSL'
290N/APOVER = '0.7'
290N/APOARC = '%s-%s.tar.gz' % (PO, POVER)
290N/APODIR = '%s-%s' % (PO, POVER)
290N/APOURL = 'http://downloads.sourceforge.net/pyopenssl/%s' % (POARC)
290N/APOHASH = 'bd072fef8eb36241852d25a9161282a051f0a63e'
290N/A
290N/AFL = 'figleaf'
290N/AFLIDIR = 'figleaf'
290N/AFLVER = 'latest'
290N/AFLARC = '%s-%s.tar.gz' % (FL, FLVER)
290N/AFLDIR = '%s-%s' % (FL, FLVER)
290N/AFLURL = 'http://darcs.idyll.org/~t/projects/%s' % FLARC
395N/A# No hash, since we always fetch the latest
290N/AFLHASH = None
290N/A
290N/ALDTP = 'ldtp'
290N/ALDTPIDIR = 'ldtp'
290N/ALDTPVER = '1.7.1'
395N/ALDTPMINORVER = '1.7.x'
395N/ALDTPMAJORVER = '1.x'
395N/ALDTPARC = '%s-%s.tar.gz' % (LDTP, LDTPVER)
395N/ALDTPDIR = '%s-%s' % (LDTP, LDTPVER)
395N/ALDTPURL = 'http://download.freedesktop.org/ldtp/%s/%s/%s' % \
424N/A (LDTPMAJORVER, LDTPMINORVER, LDTPARC)
395N/ALDTPHASH = 'd31213d2b1449a0dadcace723b9ff7041169f7ce'
395N/A
395N/AMAKO = 'Mako'
395N/AMAKOIDIR = 'mako'
395N/AMAKOVER = '0.2.2'
290N/AMAKOARC = '%s-%s.tar.gz' % (MAKO, MAKOVER)
290N/AMAKODIR = '%s-%s' % (MAKO, MAKOVER)
395N/AMAKOURL = 'http://www.makotemplates.org/downloads/%s' % (MAKOARC)
395N/AMAKOHASH = '85c04ab3a6a26a1cab47067449712d15a8b29790'
395N/A
395N/APLY = 'ply'
395N/APLYIDIR = 'ply'
395N/APLYVER = '3.1'
395N/APLYARC = '%s-%s.tar.gz' % (PLY, PLYVER)
395N/APLYDIR = '%s-%s' % (PLY, PLYVER)
395N/APLYURL = 'http://www.dabeaz.com/ply/%s' % (PLYARC)
395N/APLYHASH = '38efe9e03bc39d40ee73fa566eb9c1975f1a8003'
395N/A
395N/APC = 'pycurl'
395N/APCIDIR = 'pycurl'
290N/APCVER = '7.19.0'
290N/APCARC = '%s-%s.tar.gz' % (PC, PCVER)
395N/APCDIR = '%s-%s' % (PC, PCVER)
395N/APCURL = 'http://pycurl.sourceforge.net/download/%s' % PCARC
395N/APCHASH = '3fb59eca1461331bb9e9e8d6fe3b23eda961a416'
395N/A
395N/Aosname = platform.uname()[0].lower()
395N/Aostype = arch = 'unknown'
395N/Aif osname == 'sunos':
395N/A arch = platform.processor()
395N/A ostype = "posix"
395N/Aelif osname == 'linux':
395N/A arch = "linux_" + platform.machine()
395N/A ostype = "posix"
395N/Aelif osname == 'windows':
290N/A arch = osname
290N/A ostype = "windows"
395N/Aelif osname == 'darwin':
395N/A arch = osname
395N/A ostype = "posix"
395N/Aelif osname == 'aix':
395N/A arch = "aix"
395N/A ostype = "posix"
395N/A
290N/Apwd = os.path.normpath(sys.path[0])
395N/A
413N/A#
413N/A# Unbuffer stdout and stderr. This helps to ensure that subprocess output
413N/A# is properly interleaved with output from this program.
395N/A#
395N/Asys.stdout = os.fdopen(sys.stdout.fileno(), "w", 0)
413N/Asys.stderr = os.fdopen(sys.stderr.fileno(), "w", 0)
395N/A
395N/Adist_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "dist_" + arch))
413N/Abuild_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "build_" + arch))
395N/Aif "ROOT" in os.environ and os.environ["ROOT"] != "":
395N/A root_dir = os.environ["ROOT"]
395N/Aelse:
395N/A root_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "root_" + arch))
395N/Apkgs_dir = os.path.normpath(os.path.join(pwd, os.pardir, "packages", arch))
395N/Aextern_dir = os.path.normpath(os.path.join(pwd, "extern"))
395N/A
395N/Acacert_dir = os.path.normpath(os.path.join(pwd, "cacert"))
424N/Acacert_install_dir = 'usr/share/pkg/cacert'
395N/A
395N/Apy_install_dir = 'usr/lib/python2.4/vendor-packages'
395N/A
395N/Ascripts_dir = 'usr/bin'
395N/Alib_dir = 'usr/lib'
395N/Asvc_method_dir = 'lib/svc/method'
395N/A
395N/Aman1_dir = 'usr/share/man/cat1'
395N/Aman1m_dir = 'usr/share/man/cat1m'
395N/Aman5_dir = 'usr/share/man/cat5'
395N/Aresource_dir = 'usr/share/lib/pkg'
395N/Asmf_dir = 'var/svc/manifest/application'
395N/Azones_dir = 'etc/zones'
395N/Aetcbrand_dir = 'etc/brand/ipkg'
395N/Abrand_dir = 'usr/lib/brand/ipkg'
395N/Aexecattrd_dir = 'etc/security/exec_attr.d'
395N/Aauthattrd_dir = 'etc/security/auth_attr.d'
395N/A
395N/Ascripts_sunos = {
395N/A scripts_dir: [
395N/A ['client.py', 'pkg'],
395N/A ['pkgdep.py', 'pkgdep'],
395N/A ['util/publish/pkgmogrify.py', 'pkgmogrify'],
290N/A ['publish.py', 'pkgsend'],
395N/A ['pull.py', 'pkgrecv'],
395N/A ['packagemanager.py', 'packagemanager'],
395N/A ['updatemanager.py', 'pm-updatemanager'],
395N/A ],
290N/A lib_dir: [
290N/A ['depot.py', 'pkg.depotd'],
290N/A ['updatemanagernotifier.py', 'updatemanagernotifier'],
290N/A ['checkforupdates.py', 'pm-checkforupdates'],
290N/A ['launch.py', 'pm-launch'],
290N/A ],
290N/A svc_method_dir: [
290N/A ['svc/svc-pkg-depot', 'svc-pkg-depot'],
290N/A ],
290N/A }
290N/A
290N/Ascripts_windows = {
290N/A scripts_dir: [
290N/A ['client.py', 'client.py'],
395N/A ['publish.py', 'publish.py'],
395N/A ['pull.py', 'pull.py'],
290N/A ['scripts/pkg.bat', 'pkg.bat'],
290N/A ['scripts/pkgsend.bat', 'pkgsend.bat'],
290N/A ['scripts/pkgrecv.bat', 'pkgrecv.bat'],
290N/A ],
290N/A lib_dir: [
395N/A ['depot.py', 'depot.py'],
395N/A ['scripts/pkg.depotd.bat', 'pkg.depotd.bat'],
395N/A ],
290N/A }
395N/A
395N/Ascripts_other_unix = {
395N/A scripts_dir: [
395N/A ['client.py', 'client.py'],
290N/A ['pkgdep.py', 'pkgdep'],
290N/A ['pkgmogrify.py', 'pkgmogrify'],
290N/A ['pull.py', 'pull.py'],
290N/A ['publish.py', 'publish.py'],
290N/A ['scripts/pkg.sh', 'pkg'],
290N/A ['scripts/pkgsend.sh', 'pkgsend'],
395N/A ['scripts/pkgrecv.sh', 'pkgrecv'],
395N/A ],
290N/A lib_dir: [
395N/A ['depot.py', 'depot.py'],
395N/A ['scripts/pkg.depotd.sh', 'pkg.depotd'],
395N/A ],
395N/A }
290N/A
290N/A# indexed by 'osname'
290N/Ascripts = {
395N/A "sunos": scripts_sunos,
395N/A "linux": scripts_other_unix,
395N/A "windows": scripts_windows,
395N/A "darwin": scripts_other_unix,
395N/A "aix" : scripts_other_unix,
395N/A "unknown": scripts_sunos,
290N/A }
290N/A
290N/Aman1_files = [
290N/A 'man/packagemanager.1',
290N/A 'man/pkg.1',
290N/A 'man/pkgdep.1',
290N/A 'man/pkgmogrify.1',
290N/A 'man/pkgsend.1',
395N/A 'man/pkgrecv.1',
290N/A 'man/pm-updatemanager.1',
395N/A ]
395N/Aman1m_files = [
395N/A 'man/pkg.depotd.1m'
395N/A ]
395N/Aman5_files = [
395N/A 'man/pkg.5'
290N/A ]
290N/Apackages = [
395N/A 'pkg',
395N/A 'pkg.actions',
395N/A 'pkg.bundle',
395N/A 'pkg.client',
395N/A 'pkg.client.transport',
395N/A 'pkg.file_layout',
413N/A 'pkg.flavor',
413N/A 'pkg.portable',
413N/A 'pkg.publish',
395N/A 'pkg.server'
290N/A ]
395N/A
395N/Aweb_files = []
395N/Afor entry in os.walk("web"):
395N/A web_dir, dirs, files = entry
395N/A if not files:
395N/A continue
395N/A web_files.append((os.path.join(resource_dir, web_dir), [
395N/A os.path.join(web_dir, f) for f in files
395N/A if f != "Makefile"
395N/A ]))
290N/A
395N/Azones_files = [
290N/A 'brand/SUNWipkg.xml',
395N/A ]
395N/Abrand_files = [
395N/A 'brand/config.xml',
395N/A 'brand/platform.xml',
395N/A 'brand/pkgcreatezone',
395N/A 'brand/attach',
395N/A 'brand/clone',
395N/A 'brand/detach',
395N/A 'brand/prestate',
395N/A 'brand/poststate',
395N/A 'brand/uninstall',
395N/A 'brand/common.ksh',
395N/A ]
395N/Aetcbrand_files = [
395N/A 'brand/pkgrm.conf',
395N/A 'brand/smf_disable.conf',
395N/A ]
395N/Asmf_files = [
395N/A 'svc/pkg-server.xml',
395N/A 'svc/pkg-update.xml',
395N/A ]
395N/Aexecattrd_files = ['util/misc/exec_attr.d/SUNWipkg']
395N/Aauthattrd_files = ['util/misc/auth_attr.d/SUNWipkg']
395N/Apspawn_srcs = [
395N/A 'modules/pspawn.c'
395N/A ]
395N/Aelf_srcs = [
395N/A 'modules/elf.c',
395N/A 'modules/elfextract.c',
395N/A 'modules/liblist.c',
395N/A ]
395N/Aarch_srcs = [
395N/A 'modules/arch.c'
290N/A ]
395N/A_actions_srcs = [
395N/A 'modules/actions/_actions.c'
395N/A ]
395N/Asolver_srcs = [
290N/A 'modules/solver/solver.c',
290N/A 'modules/solver/py_solver.c'
290N/A ]
395N/Ainclude_dirs = [ 'modules' ]
395N/Alint_flags = [ '-u', '-axms', '-erroff=E_NAME_DEF_NOT_USED2' ]
290N/A
383N/A# Runs the test suite with the code coverage suite (figleaf) turned on, and
383N/A# outputs a coverage report.
395N/A# TODO: Make the cov report format an option (html, ast, cov, etc)
383N/Aclass cov_func(Command):
383N/A description = "Runs figleaf code coverage suite"
384N/A user_options = []
383N/A def initialize_options(self):
383N/A pass
383N/A def finalize_options(self):
383N/A pass
383N/A def run(self):
383N/A if not os.path.isdir(FLDIR):
422N/A prep_sw(FL, FLARC, FLDIR, FLURL,
422N/A FLHASH)
422N/A install_sw(FL, FLDIR, FLIDIR)
422N/A # Run the test suite with coverage enabled
422N/A os.putenv('PYEXE', sys.executable)
422N/A os.chdir(os.path.join(pwd, "tests"))
422N/A # Reconstruct the cmdline and send that to run.py
422N/A os.environ["PKGCOVERAGE"] = "1"
422N/A cmd = [sys.executable, "run.py"]
422N/A subprocess.call(cmd)
422N/A print "Generating coverage report in directory: '%s/cov_report'" % \
422N/A pwd
422N/A os.system("figleaf2html -d cov_report .figleaf")
422N/A
422N/A# Runs lint on the extension module source code
422N/Aclass lint_func(Command):
422N/A description = "Runs various lint tools over IPS extension source code"
383N/A user_options = []
422N/A
383N/A def initialize_options(self):
383N/A pass
383N/A
383N/A def finalize_options(self):
383N/A pass
383N/A
383N/A # Make string shell-friendly
422N/A @staticmethod
383N/A def escape(astring):
383N/A return astring.replace(' ', '\\ ')
290N/A
290N/A def run(self):
395N/A # assumes lint is on the $PATH
395N/A if osname == 'sunos' or osname == "linux":
290N/A archcmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
290N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
290N/A ['-I' + self.escape(get_python_inc())] + \
290N/A arch_srcs
290N/A elfcmd = ['lint'] + lint_flags + \
290N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
290N/A ['-I' + self.escape(get_python_inc())] + \
290N/A ["%s%s" % ("-l", k) for k in elf_libraries] + \
290N/A elf_srcs
290N/A _actionscmd = ['lint'] + lint_flags + \
290N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
395N/A ['-I' + self.escape(get_python_inc())] + \
290N/A _actions_srcs
395N/A pspawncmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
290N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
395N/A ['-I' + self.escape(get_python_inc())] + \
290N/A pspawn_srcs
395N/A
395N/A print(" ".join(archcmd))
290N/A os.system(" ".join(archcmd))
290N/A print(" ".join(elfcmd))
290N/A os.system(" ".join(elfcmd))
290N/A print(" ".join(_actionscmd))
290N/A os.system(" ".join(_actionscmd))
290N/A print(" ".join(pspawncmd))
290N/A os.system(" ".join(pspawncmd))
290N/A
290N/A proto = os.path.join(root_dir, py_install_dir)
290N/A sys.path.insert(0, proto)
290N/A
290N/A # Insert tests directory onto sys.path so any custom checkers
290N/A # can be found.
290N/A sys.path.insert(0, os.path.join(pwd, 'tests'))
395N/A print(sys.path)
290N/A
395N/A # assumes pylint is accessible on the sys.path
395N/A from pylint import lint
290N/A scriptlist = [ 'setup.py' ]
290N/A for d, m in scripts_sunos.items():
395N/A for a in m:
395N/A # specify the filenames of the scripts, in addition
290N/A # to the package names themselves
395N/A scriptlist.append(os.path.join(root_dir, d, a[1]))
395N/A
290N/A # For some reason, the load-plugins option, when used in the
290N/A # rcfile, does not work, so we put it here instead, to load
290N/A # our custom checkers.
290N/A lint.Run(['--load-plugins=multiplatform', '--rcfile',
395N/A os.path.join(pwd, 'tests', 'pylintrc')] +
395N/A scriptlist + packages)
290N/A
290N/Aclass install_func(_install):
290N/A def initialize_options(self):
290N/A _install.initialize_options(self)
290N/A
290N/A # PRIVATE_BUILD set in the environment tells us to put the build
290N/A # directory into the .pyc files, rather than the final
395N/A # installation directory.
395N/A private_build = os.getenv("PRIVATE_BUILD", None)
395N/A
395N/A if private_build is None:
395N/A self.install_lib = py_install_dir
395N/A self.install_data = os.path.sep
395N/A self.root = root_dir
395N/A else:
395N/A self.install_lib = os.path.join(root_dir, py_install_dir)
395N/A self.install_data = root_dir
395N/A
290N/A # This is used when installing scripts, below, but it isn't a
383N/A # standard distutils variable.
395N/A self.root_dir = root_dir
395N/A
395N/A def run(self):
395N/A """
395N/A At the end of the install function, we need to rename some files
290N/A because distutils provides no way to rename files as they are
290N/A placed in their install locations.
395N/A Also, make sure that cherrypy and other external dependencies
395N/A are installed.
395N/A """
395N/A for f in man1_files + man1m_files + man5_files:
395N/A file_util.copy_file(f + ".txt", f, update=1)
395N/A
290N/A _install.run(self)
290N/A
395N/A for d, files in scripts[osname].iteritems():
395N/A for (srcname, dstname) in files:
395N/A dst_dir = util.change_root(self.root_dir, d)
395N/A dst_path = util.change_root(self.root_dir,
290N/A os.path.join(d, dstname))
395N/A dir_util.mkpath(dst_dir, verbose = True)
395N/A file_util.copy_file(srcname, dst_path, update = True)
395N/A # make scripts executable
395N/A os.chmod(dst_path,
395N/A os.stat(dst_path).st_mode
395N/A | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
395N/A
395N/A # Take cacerts in cacert_dir and install them in
290N/A # proto-area-relative cacert_install_dir
395N/A install_cacerts()
395N/A
395N/A prep_sw(CP, CPARC, CPDIR, CPURL, CPHASH)
395N/A install_sw(CP, CPDIR, CPIDIR)
395N/A if osname == "sunos" and platform.uname()[2] == "5.11":
395N/A prep_sw(LDTP, LDTPARC, LDTPDIR, LDTPURL,
395N/A LDTPHASH)
395N/A saveenv = os.environ.copy()
395N/A os.environ["LDFLAGS"] = os.environ.get("LDFLAGS", "") + \
395N/A " -lsocket -lnsl"
395N/A install_ldtp(LDTP, LDTPDIR, LDTPIDIR)
395N/A os.environ = saveenv
395N/A
395N/A if "BUILD_PYOPENSSL" in os.environ and \
395N/A os.environ["BUILD_PYOPENSSL"] != "":
395N/A #
395N/A # Include /usr/sfw/lib in the build environment
395N/A # to ensure that this builds and runs on older
395N/A # nevada builds, before openssl moved out of /usr/sfw.
395N/A #
395N/A saveenv = os.environ.copy()
395N/A if osname == "sunos":
395N/A os.environ["CFLAGS"] = "-I/usr/sfw/include " + \
395N/A os.environ.get("CFLAGS", "")
395N/A os.environ["LDFLAGS"] = \
395N/A "-L/usr/sfw/lib -R/usr/sfw/lib " + \
os.environ.get("LDFLAGS", "")
prep_sw(PO, POARC, PODIR, POURL,
POHASH)
install_sw(PO, PODIR, POIDIR)
os.environ = saveenv
prep_sw(MAKO, MAKOARC, MAKODIR, MAKOURL,
MAKOHASH)
install_sw(MAKO, MAKODIR, MAKOIDIR)
prep_sw(PLY, PLYARC, PLYDIR, PLYURL,
PLYHASH)
install_sw(PLY, PLYDIR, PLYIDIR)
prep_sw(PC, PCARC, PCDIR, PCURL, PCHASH)
install_sw(PC, PCDIR, PCIDIR)
# Remove some bits that we're not going to package, but be sure
# not to complain if we try to remove them twice.
def onerror(func, path, exc_info):
if exc_info[1].errno != errno.ENOENT:
raise
for dir in ("cherrypy/scaffold", "cherrypy/test",
"cherrypy/tutorial"):
shutil.rmtree(os.path.join(root_dir, py_install_dir, dir),
onerror=onerror)
try:
os.remove(os.path.join(root_dir, "usr/bin/mako-render"))
except EnvironmentError, e:
if e.errno != errno.ENOENT:
raise
def hash_sw(swname, swarc, swhash):
if swhash == None:
return True
print "checksumming %s" % swname
hash = sha.new()
f = open(swarc, "rb")
while True:
data = f.read(65536)
if data == "":
break
hash.update(data)
f.close()
if hash.hexdigest() == swhash:
return True
else:
print >> sys.stderr, "bad checksum! %s != %s" % \
(swhash, hash.hexdigest())
return False
def install_cacerts():
findir = os.path.join(root_dir, cacert_install_dir)
dir_util.mkpath(findir, verbose = True)
for f in os.listdir(cacert_dir):
# Copy certificate
srcname = os.path.normpath(os.path.join(cacert_dir, f))
dn, copied = file_util.copy_file(srcname, findir, update = True)
if not copied:
continue
# Call openssl to create hash symlink
cmd = ["openssl", "x509", "-noout", "-hash", "-in",
srcname]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
hashval = p.stdout.read()
p.wait()
hashval = hashval.strip()
hashval += ".0"
hashpath = os.path.join(findir, hashval)
if os.path.exists(hashpath):
os.unlink(hashpath)
if hasattr(os, "symlink"):
os.symlink(f, hashpath)
else:
file_util.copy_file(srcname, hashpath)
def prep_sw(swname, swarc, swdir, swurl, swhash):
swarc = os.path.join(extern_dir, swarc)
swdir = os.path.join(extern_dir, swdir)
if not os.path.exists(extern_dir):
os.mkdir(extern_dir)
if not os.path.exists(swarc):
print "downloading %s" % swname
try:
fname, hdr = urllib.urlretrieve(swurl, swarc)
except IOError:
pass
if not os.path.exists(swarc) or \
(hdr.gettype() != "application/x-gzip" and
hdr.gettype() != "application/x-tar"):
print >> sys.stderr, "Unable to retrieve %s.\n" \
"Please retrieve the file " \
"and place it at: %s\n" % (swurl, swarc)
# remove a partial download or error message from proxy
remove_sw(swname)
sys.exit(1)
if not os.path.exists(swdir):
if not hash_sw(swname, swarc, swhash):
sys.exit(1)
print "unpacking %s" % swname
tar = tarfile.open(swarc)
# extractall doesn't exist until python 2.5
for m in tar.getmembers():
tar.extract(m, extern_dir)
tar.close()
# If there are patches, apply them now.
patchdir = os.path.join("patch", swname)
already_patched = os.path.join(swdir, ".patched")
if os.path.exists(patchdir) and not os.path.exists(already_patched):
patches = os.listdir(patchdir)
for p in patches:
patchpath = os.path.join(os.path.pardir,
os.path.pardir, patchdir, p)
print "Applying %s to %s" % (p, swname)
args = ["patch", "-d", swdir, "-i", patchpath, "-p0"]
if osname == "windows":
args.append("--binary")
ret = subprocess.Popen(args).wait()
if ret != 0:
print >> sys.stderr, \
"patch failed and returned %d." % ret
print >> sys.stderr, \
"Command was: %s" % " ".join(args)
sys.exit(1)
file(already_patched, "w").close()
def install_ldtp(swname, swdir, swidir):
swdir = os.path.join(extern_dir, swdir)
swinst_file = os.path.join(root_dir, py_install_dir, swidir + ".py")
if not os.path.exists(swinst_file):
print "installing %s" % swname
args_config = ['./configure',
'--prefix=/usr',
'--bindir=/usr/bin',
'PYTHONPATH=""',
]
args_make_install = ['make', 'install',
'DESTDIR=%s' % root_dir
]
run_cmd(args_config, swdir)
run_cmd(args_make_install, swdir)
def install_sw(swname, swdir, swidir):
swdir = os.path.join(extern_dir, swdir)
swinst_dir = os.path.join(root_dir, py_install_dir, swidir)
if not os.path.exists(swinst_dir):
print "installing %s" % swname
args = ['python', 'setup.py', 'install',
'--root=%s' % root_dir,
'--install-lib=%s' % py_install_dir,
'--install-data=%s' % py_install_dir]
run_cmd(args, swdir)
def run_cmd(args, swdir):
ret = subprocess.Popen(args, cwd = swdir).wait()
if ret != 0:
print >> sys.stderr, \
"install failed and returned %d." % ret
print >> sys.stderr, \
"Command was: %s" % " ".join(args)
sys.exit(1)
def remove_sw(swname):
print("deleting %s" % swname)
for file in os.listdir(extern_dir):
if fnmatch.fnmatch(file, "%s*" % swname):
fpath = os.path.join(extern_dir, file)
if os.path.isfile(fpath):
os.unlink(fpath)
else:
shutil.rmtree(fpath, True)
class build_func(_build):
def initialize_options(self):
_build.initialize_options(self)
self.build_base = build_dir
def get_hg_version():
try:
p = subprocess.Popen(['hg', 'id', '-i'], stdout = subprocess.PIPE)
return p.communicate()[0].strip()
except OSError:
print >> sys.stderr, "ERROR: unable to obtain mercurial version"
return "unknown"
def syntax_check(filename):
""" Run python's compiler over the file, and discard the results.
Arrange to generate an exception if the file does not compile.
This is needed because distutil's own use of pycompile (in the
distutils.utils module) is broken, and doesn't stop on error. """
try:
py_compile.compile(filename, os.devnull, doraise=True)
except py_compile.PyCompileError, e:
raise DistutilsError("%s: failed syntax check: %s" %
(filename, e))
class build_py_func(_build_py):
# override the build_module method to do VERSION substitution on pkg/__init__.py
def build_module (self, module, module_file, package):
if module == "__init__" and package == "pkg":
versionre = '(?m)^VERSION[^"]*"([^"]*)"'
# Grab the previously-built version out of the build
# tree.
try:
ocontent = \
file(self.get_module_outfile(self.build_lib,
[package], module)).read()
ov = re.search(versionre, ocontent).group(1)
except IOError:
ov = None
v = get_hg_version()
vstr = 'VERSION = "%s"' % v
# If the versions haven't changed, there's no need to
# recompile.
if v == ov:
return
mcontent = file(module_file).read()
mcontent = re.sub(versionre, vstr, mcontent)
tmpfd, tmp_file = tempfile.mkstemp()
os.write(tmpfd, mcontent)
os.close(tmpfd)
print "doing version substitution: ", v
rv = _build_py.build_module(self, module, tmp_file, package)
os.unlink(tmp_file)
return rv
# Will raise a DistutilsError on failure.
syntax_check(module_file)
return _build_py.build_module(self, module, module_file, package)
class clean_func(_clean):
def initialize_options(self):
_clean.initialize_options(self)
self.build_base = build_dir
class clobber_func(Command):
user_options = []
description = "Deletes any and all files created by setup"
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
# nuke everything
print("deleting " + dist_dir)
shutil.rmtree(dist_dir, True)
print("deleting " + build_dir)
shutil.rmtree(build_dir, True)
print("deleting " + root_dir)
shutil.rmtree(root_dir, True)
print("deleting " + pkgs_dir)
shutil.rmtree(pkgs_dir, True)
print("deleting " + extern_dir)
shutil.rmtree(extern_dir, True)
class test_func(Command):
# NOTE: these options need to be in sync with tests/run.py and the
# list of options stored in initialize_options below. The first entry
# in each tuple must be the exact name of a member variable.
user_options = [("verbosemode", 'v', "run tests in verbose mode"),
("genbaseline", 'g', "generate test baseline"),
("parseable", 'p', "parseable output"),
("timing", "t", "timing file <file>"),
("baselinefile=", 'b', "baseline file <file>"),
("only=", "o", "only <regex>")]
description = "Runs unit and functional tests"
def initialize_options(self):
self.only = ""
self.baselinefile = ""
self.verbosemode = 0
self.parseable = 0
self.genbaseline = 0
self.timing = 0
def finalize_options(self):
pass
def run(self):
os.putenv('PYEXE', sys.executable)
os.chdir(os.path.join(pwd, "tests"))
# Reconstruct the cmdline and send that to run.py
cmd = [sys.executable, "run.py"]
args = ""
if "test" in sys.argv:
args = sys.argv[sys.argv.index("test")+1:]
cmd.extend(args)
subprocess.call(cmd)
class dist_func(_bdist):
def initialize_options(self):
_bdist.initialize_options(self)
self.dist_dir = dist_dir
# These are set to real values based on the platform, down below
compile_args = None
link_args = None
ext_modules = [
Extension(
'actions._actions',
_actions_srcs,
include_dirs = include_dirs,
extra_compile_args = compile_args,
extra_link_args = link_args
),
]
elf_libraries = None
data_files = web_files
cmdclasses = {
'install': install_func,
'build': build_func,
'build_py': build_py_func,
'bdist': dist_func,
'lint': lint_func,
'clean': clean_func,
'clobber': clobber_func,
'coverage': cov_func,
'test': test_func,
}
# all builds of IPS should have manpages
data_files += [
(man1_dir, man1_files),
(man1m_dir, man1m_files),
(man5_dir, man5_files),
]
if osname == 'sunos':
# Solaris-specific extensions are added here
data_files += [
(zones_dir, zones_files),
(brand_dir, brand_files),
(etcbrand_dir, etcbrand_files),
(smf_dir, smf_files),
(execattrd_dir, execattrd_files),
(authattrd_dir, authattrd_files),
]
if osname == 'sunos' or osname == "linux":
# Unix platforms which the elf extension has been ported to
# are specified here, so they are built automatically
elf_libraries = ['elf']
ext_modules += [
Extension(
'elf',
elf_srcs,
include_dirs = include_dirs,
libraries = elf_libraries,
extra_compile_args = compile_args,
extra_link_args = link_args
),
]
# Solaris has built-in md library and Solaris-specific arch extension
# All others use OpenSSL and cross-platform arch module
if osname == 'sunos':
elf_libraries += [ 'md' ]
ext_modules += [
Extension(
'arch',
arch_srcs,
include_dirs = include_dirs,
extra_compile_args = compile_args,
extra_link_args = link_args,
define_macros = [('_FILE_OFFSET_BITS', '64')]
),
Extension(
'pspawn',
pspawn_srcs,
include_dirs = include_dirs,
extra_compile_args = compile_args,
extra_link_args = link_args,
define_macros = [('_FILE_OFFSET_BITS', '64')]
),
Extension(
'solver',
solver_srcs,
include_dirs = include_dirs + ["."],
extra_compile_args = compile_args,
extra_link_args = [
"-ztext",
"-lm",
"-lc"
],
define_macros = [('_FILE_OFFSET_BITS', '64')]
)
]
else:
elf_libraries += [ 'ssl' ]
setup(cmdclass = cmdclasses,
name = 'ips',
version = '1.0',
package_dir = {'pkg':'modules'},
packages = packages,
data_files = data_files,
ext_package = 'pkg',
ext_modules = ext_modules,
)