setup.py revision 290
409N/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#
290N/A
395N/Aimport os
395N/Aimport stat
395N/Aimport sys
290N/Aimport platform
454N/Aimport shutil
290N/Aimport code
448N/Aimport subprocess
290N/Aimport tempfile
290N/A
290N/Afrom distutils.core import setup, Extension
383N/Afrom distutils.cmd import Command
290N/Afrom distutils.command.install import install as _install
395N/Afrom distutils.command.build import build as _build
290N/Afrom distutils.command.bdist import bdist as _bdist
395N/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
383N/A
290N/Apwd = os.path.normpath(sys.path[0])
290N/A
290N/Aosname = platform.uname()[0].lower()
290N/Aostype = arch = 'unknown'
290N/Aif osname == 'sunos':
290N/A arch = platform.processor()
290N/A ostype = "posix"
290N/Aelif osname == 'linux':
465N/A arch = "linux_" + platform.machine()
465N/A ostype = "posix"
465N/Aelif osname == 'windows':
465N/A arch = osname
465N/A ostype = "windows"
465N/Aelif osname == 'darwin':
465N/A arch = osname
465N/A ostype = "posix"
465N/A
465N/Adist_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "dist_" + arch))
465N/Abuild_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "build_" + arch))
465N/Aroot_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "root_" + arch))
465N/A
465N/Apy_install_dir = 'usr/lib/python2.4/vendor-packages'
465N/A
290N/Ascripts_dir = 'usr/bin'
290N/Alib_dir = 'usr/lib'
290N/A
395N/Aman1_dir = 'usr/share/man/cat1'
395N/Aman1m_dir = 'usr/share/man/cat1m'
290N/Aman5_dir='usr/share/man/cat5'
395N/Aresource_dir = 'usr/share/lib/pkg'
395N/Asmf_dir = 'var/svc/manifest/application'
290N/Azones_dir = 'etc/zones'
395N/Abrand_dir = 'usr/lib/brand/ipkg'
395N/A
290N/Ascripts_sunos = {
395N/A scripts_dir : [
395N/A ['client.py', 'pkg'],
290N/A ['publish.py', 'pkgsend'],
448N/A ],
448N/A lib_dir : [
534N/A ['depot.py', 'pkg.depotd'],
534N/A ],
534N/A }
534N/A
534N/Ascripts_windows = {
534N/A scripts_dir : [
534N/A ['client.py', 'client.py'],
290N/A ['publish.py', 'publish.py'],
290N/A ['scripts/pkg.bat', 'pkg.bat'],
290N/A ['scripts/pkgsend.bat', 'pkgsend.bat'],
534N/A ],
290N/A lib_dir : [
290N/A ['depot.py', 'depot.py'],
290N/A ['scripts/pkg.depotd.bat', 'pkg.depotd.bat'],
290N/A ],
290N/A }
290N/A
290N/Ascripts_other_unix = {
290N/A scripts_dir : [
395N/A ['client.py', 'client.py'],
290N/A ['publish.py', 'publish.py'],
290N/A ['scripts/pkg.sh', 'pkg'],
290N/A ['scripts/pkgsend.sh', 'pkgsend'],
290N/A ],
290N/A lib_dir : [
395N/A ['depot.py', 'depot.py'],
430N/A ['scripts/pkg.depotd.sh', 'pkg.depotd'],
395N/A ],
395N/A }
395N/A
424N/A# indexed by 'osname'
578N/Ascripts = { "sunos" : scripts_sunos,
395N/A "linux" : scripts_other_unix,
395N/A "windows" : scripts_windows,
395N/A "darwin" : scripts_other_unix,
578N/A "unknown" : scripts_sunos,
395N/A }
395N/A
290N/Aman1_files= [
290N/A 'man/pkg.1.txt',
395N/A 'man/pkgsend.1.txt',
395N/A ]
395N/Aman1m_files = [
395N/A 'man/pkg.depotd.1m.txt'
395N/A ]
395N/Aman5_files = [
395N/A 'man/pkg.5.txt'
395N/A ]
395N/Apackages = [
395N/A 'pkg',
395N/A 'pkg.actions',
395N/A 'pkg.bundle',
395N/A 'pkg.client',
290N/A 'pkg.portable',
290N/A 'pkg.publish',
395N/A 'pkg.server',
395N/A ]
395N/A
395N/Aweb_files = [
395N/A 'web/pkg-block-icon.png',
395N/A 'web/pkg-block-logo.png',
395N/A 'web/pkg.css',
395N/A 'web/robots.txt',
395N/A ]
395N/A
395N/Azones_files = [
395N/A 'brand/SUNWipkg.xml',
395N/A ]
290N/A
290N/Abrand_files = [
430N/A 'brand/config.xml',
395N/A 'brand/platform.xml',
395N/A 'brand/pkgcreatezone',
395N/A ]
395N/Asmf_files = [
395N/A 'pkg-server.xml',
395N/A ]
290N/A
395N/Aelf_srcs = [
413N/A 'modules/elf.c',
413N/A 'modules/elfextract.c',
413N/A 'modules/liblist.c',
395N/A ]
395N/A
413N/Aarch_srcs = [
395N/A 'modules/arch.c'
395N/A ]
413N/A
395N/Ainclude_dirs = ['modules']
395N/A
395N/Alint_flags = [ '-u', '-axms', '-erroff=E_NAME_DEF_NOT_USED2' ]
395N/A
395N/A# Runs lint on the extension module source code
395N/Aclass lint_func(Command):
395N/A description = "Runs various lint tools over IPS extension source code"
395N/A user_options = []
424N/A
395N/A def initialize_options(self):
395N/A pass
395N/A
395N/A def finalize_options(self):
395N/A pass
451N/A
395N/A # Make string shell-friendly
395N/A @staticmethod
395N/A def escape(string):
395N/A return string.replace(' ', '\\ ')
395N/A
395N/A def run(self):
395N/A # assumes lint is on the $PATH
395N/A if osname == 'sunos' or osname == "linux":
395N/A archcmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
395N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
395N/A ['-I' + self.escape(get_python_inc())] + \
395N/A arch_srcs
578N/A elfcmd = ['lint'] + lint_flags + \
395N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
395N/A ['-I' + self.escape(get_python_inc())] + \
395N/A ["%s%s" % ("-l", k) for k in elf_libraries] + \
395N/A elf_srcs
395N/A
395N/A print(" ".join(archcmd))
290N/A os.system(" ".join(archcmd))
395N/A print(" ".join(elfcmd))
395N/A os.system(" ".join(elfcmd))
591N/A
591N/A proto = "%s/%s" % (root_dir, py_install_dir)
591N/A sys.path.insert(0, proto)
395N/A
395N/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'))
290N/A print(sys.path)
290N/A
290N/A # assumes pylint is accessible on the sys.path
290N/A from pylint import lint
290N/A scriptlist=[]
290N/A for dir,map in scripts_sunos.items():
290N/A for arr in map:
290N/A # specify the filenames of the scripts, in addition
290N/A # to the package names themselves
290N/A scriptlist.append(os.path.join(root_dir, dir, arr[1]))
290N/A
290N/A # For some reason, the load-plugins option, when used in the
395N/A # rcfile, does not work, so we put it here instead, to load
395N/A # our custom checkers.
290N/A lint.Run(['--load-plugins=multiplatform', '--rcfile',
290N/A os.path.join(pwd, 'tests', 'pylintrc')] +
290N/A scriptlist + packages)
290N/A
290N/A# Developer command to connect the local machine to the current
395N/A# repository's working copy's versions of the commands, modules, and supporting
395N/A# files.
395N/Aclass link_func(Command):
290N/A user_options = []
395N/A description = "Developer command to connect local machine to working " \
395N/A "copy of files in local repository"
395N/A
395N/A def initialize_options(self):
591N/A pass
591N/A def finalize_options(self):
591N/A pass
591N/A
290N/A def run(self):
290N/A os.system('mkdir -p /usr/share/lib/pkg')
290N/A os.system('mkdir -p /usr/lib/brand/ipkg')
290N/A os.system('mkdir -p /usr/share/man/cat1')
290N/A os.system('mkdir -p /usr/share/man/cat1m')
591N/A os.system('mkdir -p /usr/share/man/cat5')
591N/A
290N/A os.system('ln -sf ' + pwd + '/client.py /usr/bin/pkg')
395N/A os.system('ln -sf ' + pwd + '/publish.py /usr/bin/pkgsend')
395N/A os.system('ln -sf ' + pwd + '/depot.py /usr/bin/pkg.depotd')
290N/A os.system('ln -sf ' + pwd + '/modules ' + '/' + py_install_dir + '/pkg')
395N/A os.system('ln -sf ' + pwd + \
395N/A '/pkg-server.xml /var/svc/manifest/pkg-server.xml')
395N/A os.system('ln -sf ' + pwd + \
395N/A '/web/pkg-block-icon.png /usr/share/lib/pkg/pkg-block-icon.png')
290N/A os.system('ln -sf ' + pwd + \
290N/A '/web/pkg-block-logo.png /usr/share/lib/pkg/pkg-block-logo.png')
290N/A os.system('ln -sf ' + pwd + \
395N/A '/web/pkg.css /usr/share/lib/pkg/pkg.css')
395N/A os.system('ln -sf ' + pwd + \
395N/A '/brand/config.xml /usr/lib/brand/ipkg/config.xml')
395N/A os.system('ln -sf ' + pwd + \
395N/A '/brand/platform.xml /usr/lib/brand/ipkg/platform.xml')
395N/A os.system('ln -sf ' + pwd +
290N/A '/brand/pkgcreatezone /usr/lib/brand/ipkg/pkgcreatezone')
290N/A os.system('ln -sf ' + pwd + \
290N/A '/brand/SUNWipkg.xml /etc/zones/SUNWipkg.xml')
290N/A os.system('ln -sf ' + pwd + '/man/pkg.1.txt /usr/share/man/cat1/pkg.1')
290N/A os.system('ln -sf ' + pwd + \
430N/A '/man/pkgsend.1.txt /usr/share/man/cat1/pkgsend.1')
290N/A os.system('ln -sf ' + pwd + \
290N/A '/man/pkg.depotd.1m.txt /usr/share/man/cat1m/pkg.depotd.1m')
395N/A os.system('ln -sf ' + pwd + '/man/pkg.5.txt /usr/share/man/man5/pkg.5')
290N/A
395N/Aclass link_clean_func(Command):
506N/A user_options = []
506N/A description = "Cleans up links created by the \"link\" command"
506N/A
506N/A def initialize_options(self):
506N/A pass
506N/A def finalize_options(self):
395N/A pass
506N/A
506N/A def run(self):
513N/A
506N/A os.system('rm -f /usr/bin/pkg')
506N/A os.system('rm -f /usr/bin/pkgsend')
506N/A os.system('rm -f /usr/lib/pkg.depotd')
513N/A os.system('rm -f ' + '/' + py_install_dir + '/pkg')
506N/A os.system('rm -f /var/svc/manifest/pkg-server.xml')
506N/A os.system('rm -rf /usr/share/lib/pkg')
506N/A os.system('rm -rf /usr/lib/brand/ipkg')
506N/A os.system('rm -f /etc/zones/SUNWipkg.xml')
290N/A os.system('rm -f /usr/share/man/cat1/pkg.1')
290N/A os.system('rm -f /usr/share/man/cat1/pkgsend.1')
395N/A os.system('rm -f /usr/share/man/cat1m/pkg.depotd.1m')
395N/A os.system('rm -f /usr/share/man/man5/pkg.5')
395N/A
395N/Aclass install_func(_install):
395N/A def initialize_options(self):
395N/A _install.initialize_options(self)
413N/A # It's OK to have /'s here, python figures it out when writing files
413N/A self.install_purelib = py_install_dir
413N/A self.install_platlib = py_install_dir
395N/A self.root = root_dir
290N/A self.prefix = '.'
395N/A
395N/A # At the end of the install function, we need to rename some files
506N/A # because distutils provides no way to rename files as they are placed
506N/A # in their install locations
395N/A def run(self):
395N/A _install.run(self)
395N/A if ostype == 'posix':
395N/A # only rename manpages if building for unix-derived OS
430N/A for (dir, files) in [(man1_dir, man1_files), (man1m_dir,
395N/A man1m_files), (man5_dir, man5_files)]:
290N/A for file in files:
465N/A src = util.change_root(self.root, os.path.join(dir,
465N/A os.path.basename(file)))
290N/A if src.endswith('.txt'):
465N/A dst = src[:-4]
465N/A file_util.copy_file(src, dst, update=True)
465N/A
395N/A for dir, files in scripts[osname].iteritems():
465N/A for (srcname, dstname) in files:
395N/A dst_dir = util.change_root(self.root, dir)
395N/A dst_path = util.change_root(self.root,
465N/A os.path.join(dir, dstname))
465N/A dir_util.mkpath(dst_dir, verbose=True)
465N/A file_util.copy_file(srcname, dst_path, update=True)
395N/A # make scripts executable
465N/A os.chmod(dst_path, os.stat(dst_path).st_mode | stat.S_IEXEC)
395N/A
465N/Aclass build_func(_build):
395N/A def initialize_options(self):
465N/A _build.initialize_options(self)
465N/A self.build_base = build_dir
465N/A
395N/Aclass clean_func(_clean):
395N/A def initialize_options(self):
395N/A _clean.initialize_options(self)
395N/A self.build_base = build_dir
465N/A
465N/Aclass clobber_func(Command):
465N/A user_options = []
395N/A description = "Deletes any and all files created by setup"
498N/A
498N/A def initialize_options(self):
498N/A pass
498N/A def finalize_options(self):
290N/A pass
465N/A def run(self):
465N/A # nuke everything
465N/A print("Deleting " + dist_dir)
454N/A shutil.rmtree(dist_dir, True)
465N/A print("Deleting " + build_dir)
454N/A shutil.rmtree(build_dir, True)
454N/A print("Deleting " + root_dir)
454N/A shutil.rmtree(root_dir, True)
454N/A
465N/Aclass test_func(Command):
290N/A user_options = []
430N/A description = "Runs unit and functional tests"
395N/A
395N/A def initialize_options(self):
290N/A pass
383N/A def finalize_options(self):
383N/A pass
395N/A def run(self):
383N/A os.putenv('PYEXE', sys.executable)
383N/A os.chdir(os.path.join(pwd, "tests"))
384N/A testlogfd, testlogpath = tempfile.mkstemp(suffix = '.pkg-test.log')
383N/A testlogfp = os.fdopen(testlogfd, "w")
383N/A print "Logging to %s" % testlogpath
383N/A
383N/A subprocess.call([sys.executable, "api-complete.py"], stdout=testlogfp)
383N/A
383N/A if ostype == 'posix':
422N/A subprocess.call([sys.executable, "cli-complete.py"], stdout=testlogfp)
422N/A subprocess.call(["/bin/ksh", "two-depot.ksh"], stdout=testlogfp)
422N/A if osname == 'sunos':
422N/A subprocess.call(["/bin/ksh", "memleaks.ksh"], stdout=testlogfp)
422N/A testlogfp.close()
422N/A
422N/Aclass dist_func(_bdist):
422N/A def initialize_options(self):
422N/A _bdist.initialize_options(self)
422N/A self.dist_dir = dist_dir
422N/A
422N/A
422N/A# These are set to real values based on the platform, down below
422N/Aext_modules = None
422N/Acompile_args = None
422N/Alink_args = None
422N/Aelf_libraries = None
383N/Adata_files = [
422N/A (resource_dir, web_files),
383N/A ]
383N/Acmdclasses={
383N/A 'link' : link_func,
383N/A 'linkclean' : link_clean_func,
383N/A 'install' : install_func,
383N/A 'build' : build_func,
383N/A 'bdist' : dist_func,
422N/A 'lint' : lint_func,
383N/A 'clean' : clean_func,
383N/A 'clobber' : clobber_func,
290N/A 'test' : test_func,
430N/A }
395N/A
395N/Aif ostype == 'posix':
290N/A # all unix builds of IPS should have manpages
290N/A data_files += [
290N/A (man1_dir, man1_files),
290N/A (man1m_dir, man1m_files),
290N/A (man5_dir, man5_files),
290N/A ]
290N/A
290N/Aif osname == 'sunos':
290N/A # Solaris-specific extensions are added here
290N/A data_files += [
290N/A (zones_dir, zones_files),
395N/A (brand_dir, brand_files),
290N/A (smf_dir, smf_files),
395N/A ]
290N/A
395N/Aif osname == 'sunos' or osname == "linux":
290N/A # Unix platforms which the elf extension has been ported to
534N/A # are specified here, so they are built automatically
534N/A elf_libraries = ['elf']
465N/A ext_modules=[
465N/A Extension(
290N/A 'elf',
290N/A elf_srcs,
448N/A include_dirs=include_dirs,
430N/A libraries=elf_libraries,
448N/A extra_compile_args=compile_args,
448N/A extra_link_args=link_args
448N/A ),
448N/A ]
290N/A
290N/A # Solaris has built-in md library and Solaris-specific arch extension
290N/A # All others use OpenSSL and cross-platform arch module
448N/A if osname == 'sunos':
448N/A elf_libraries += ['md']
430N/A ext_modules += [
448N/A Extension(
430N/A 'arch',
290N/A arch_srcs,
290N/A include_dirs=include_dirs,
290N/A extra_compile_args=compile_args,
290N/A extra_link_args=link_args,
290N/A define_macros=[('_FILE_OFFSET_BITS', '64')]
290N/A ),
448N/A ]
448N/A else:
448N/A elf_libraries += ['ssl']
448N/A
448N/Asetup(cmdclass=cmdclasses,
430N/A name='ips',
448N/A version='1.0',
290N/A package_dir= {'pkg':'modules'},
290N/A packages=packages,
290N/A data_files=data_files,
430N/A ext_package='pkg',
395N/A ext_modules=ext_modules,
290N/A )
290N/A