diff --git a/CMakeLists.txt b/CMakeLists.txt index d15aef4f0f9..19518eba1b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,7 @@ add_subdirectory(doc) add_subdirectory(test) add_subdirectory(pki) add_subdirectory(contrib) +add_subdirectory(python) set(CPACK_PACKAGE_NAME "Icinga2") set(CPACK_PACKAGE_VENDOR "Icinga Development Team") diff --git a/INSTALL b/INSTALL index 3f9b3246c76..451e0cec85f 100644 --- a/INSTALL +++ b/INSTALL @@ -27,9 +27,9 @@ parentheses): on Debian) * GNU bison (bison) * GNU flex (flex) >= 2.5.35 +* Python (python-devel on RHEL, python-dev on Debian) * recommended: libexecinfo on FreeBSD * optional: MySQL (mysql-devel on RHEL, libmysqlclient-dev on Debian) -* optional: Python (python-devel on RHEL, python-dev on Debian) Note: RHEL5 ships an ancient flex version. Updated packages are available for example from the repoforge buildtools repository. diff --git a/icinga2.spec b/icinga2.spec index cb6130cd3cb..f11e62adb0e 100644 --- a/icinga2.spec +++ b/icinga2.spec @@ -44,6 +44,10 @@ %endif %endif +%{!?__python2: %global __python2 /usr/bin/python2} +%{!?python2_sitelib: %global python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} +%{!?python2_sitearch: %global python2_sitearch %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")} + %define icinga_user icinga %define icinga_group icinga %define icingacmd_group icingacmd @@ -63,7 +67,6 @@ Group: Applications/System Source: https://github.com/Icinga/%{name}/archive/v%{version}.tar.gz URL: http://www.icinga.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-build - Requires: %{name}-bin = %{version} #Requires: %{name}-ido-mysql = %{version} #Requires: %{icingaweb2name} >= %{icingaweb2version} @@ -75,6 +78,7 @@ Meta package for Icinga 2 Core, DB IDO and Web. Summary: Icinga 2 binaries and libraries Group: Applications/System +Requires: python-%{name} = %{version} %if "%{_vendor}" == "suse" PreReq: permissions %endif @@ -168,6 +172,17 @@ Icinga 1.x Classic UI Standalone configuration with locations for Icinga 2. +%package -n python-icinga2 +Summary: Python module for Icinga 2 +Group: Application/System +BuildRequires: python +BuildRequires: python-devel +BuildRequires: python-setuptools +Requires: python-setuptools + +%description -n python-icinga2 +Python module for Icinga 2. + %prep %setup -q -n %{name}-%{version} @@ -207,7 +222,6 @@ cmake $CMAKE_OPTS . make %{?_smp_mflags} -rm -f components/db_ido_*sql/schema/upgrade/.gitignore %install [ "%{buildroot}" != "/" ] && [ -d "%{buildroot}" ] && rm -rf %{buildroot} @@ -448,6 +462,7 @@ exit 0 %{_bindir}/%{name}-build-ca %{_bindir}/%{name}-build-key %{_bindir}/%{name}-sign-key +%{_bindir}/%{name}-list-objects %{_sbindir}/%{name}-enable-feature %{_sbindir}/%{name}-disable-feature %{_sbindir}/%{name}-prepare-dirs @@ -506,5 +521,8 @@ exit 0 %config(noreplace) %{apacheconfdir}/icinga.conf %config(noreplace) %attr(0640,root,%{apachegroup}) %{icingaclassicconfdir}/passwd +%files -n python-icinga2 +%{python2_sitelib}/icinga2* + %changelog diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt new file mode 100644 index 00000000000..e4a305f85c4 --- /dev/null +++ b/python/CMakeLists.txt @@ -0,0 +1,31 @@ +# Icinga 2 +# Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +find_package(PythonInterp REQUIRED) + +add_subdirectory(icinga2) + +configure_file(setup.py.cmake ${CMAKE_CURRENT_BINARY_DIR}/setup.py @ONLY) + +install(CODE "execute_process( + COMMAND ${CMAKE_COMMAND} + -DSETUP_PY=${CMAKE_CURRENT_BINARY_DIR}/setup.py + -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} + -DPREFIX=${CMAKE_INSTALL_PREFIX} + -DWDIR=${CMAKE_CURRENT_BINARY_DIR} + -P ${PROJECT_SOURCE_DIR}/third-party/cmake/PythonSetup.cmake)" +) diff --git a/python/icinga2/CMakeLists.txt b/python/icinga2/CMakeLists.txt new file mode 100644 index 00000000000..846637f3769 --- /dev/null +++ b/python/icinga2/CMakeLists.txt @@ -0,0 +1,23 @@ +# Icinga 2 +# Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +add_subdirectory(commands) +add_subdirectory(utils) + +configure_file(config.py.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.py @ONLY) +configure_file(__init__.py ${CMAKE_CURRENT_BINARY_DIR}/__init__.py COPYONLY) + diff --git a/python/icinga2/__init__.py b/python/icinga2/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/icinga2/commands/CMakeLists.txt b/python/icinga2/commands/CMakeLists.txt new file mode 100644 index 00000000000..b31292d447a --- /dev/null +++ b/python/icinga2/commands/CMakeLists.txt @@ -0,0 +1,20 @@ +# Icinga 2 +# Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +configure_file(__init__.py ${CMAKE_CURRENT_BINARY_DIR}/__init__.py COPYONLY) +configure_file(list_objects.py ${CMAKE_CURRENT_BINARY_DIR}/list_objects.py COPYONLY) + diff --git a/python/icinga2/commands/__init__.py b/python/icinga2/commands/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/icinga2/commands/list_objects.py b/python/icinga2/commands/list_objects.py new file mode 100644 index 00000000000..7f661e8f9da --- /dev/null +++ b/python/icinga2/commands/list_objects.py @@ -0,0 +1,24 @@ +# Icinga 2 +# Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +from icinga2.utils.debug import ObjectsFile + +def main(): + fp = open("/tmp/i2/var/cache/icinga2/icinga2.debug") + of = ObjectsFile(fp) + for obj in of: + print obj diff --git a/python/icinga2/config.py.cmake b/python/icinga2/config.py.cmake new file mode 100644 index 00000000000..9596450f7f3 --- /dev/null +++ b/python/icinga2/config.py.cmake @@ -0,0 +1,24 @@ +# Icinga 2 +# Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +Prefix = '@CMAKE_INSTALL_PREFIX@' +SysconfDir = '@CMAKE_INSTALL_FULL_SYSCONFDIR@' +RunDir = '@ICINGA2_RUNDIR@' +LocalStateDir = '@CMAKE_INSTALL_FULL_LOCALSTATEDIR@' +PkgDataDir = '@CMAKE_INSTALL_FULL_DATADIR@/icinga2' +IncludeConfDir = '@CMAKE_INSTALL_FULL_DATADIR@/icinga2/include' + diff --git a/python/icinga2/utils/CMakeLists.txt b/python/icinga2/utils/CMakeLists.txt new file mode 100644 index 00000000000..7aaabe72591 --- /dev/null +++ b/python/icinga2/utils/CMakeLists.txt @@ -0,0 +1,21 @@ +# Icinga 2 +# Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +configure_file(__init__.py ${CMAKE_CURRENT_BINARY_DIR}/__init__.py COPYONLY) +configure_file(debug.py ${CMAKE_CURRENT_BINARY_DIR}/debug.py COPYONLY) +configure_file(netstring.py ${CMAKE_CURRENT_BINARY_DIR}/netstring.py COPYONLY) + diff --git a/python/icinga2/utils/__init__.py b/python/icinga2/utils/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/icinga2/utils/debug.py b/python/icinga2/utils/debug.py new file mode 100644 index 00000000000..1e725ee335e --- /dev/null +++ b/python/icinga2/utils/debug.py @@ -0,0 +1,89 @@ +# Icinga 2 +# Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +from icinga2.utils import netstring + +try: + import json +except ImportError: + import simplejson as json + +class DebugObject: + def __init__(self, obj): + self._obj = obj + + def __str__(self): + return self.format_object() + + def format_object(self): + if self._obj["abstract"]: + result = "Template '" + else: + result = "Object '" + result += self._obj["properties"]["__name"] + "' of type '" + self._obj["type"] + "':\n" + result += self.format_properties(2) + return result + + def format_properties(self, indent=0, path=[]): + props = self._obj["properties"] + for component in path: + props = props[component] + + result = "" + for key, value in props.items(): + if path == [] and key in ['__name', 'type', 'name', 'templates']: + continue + path.append(key) + result += ' ' * indent + "* %s" % (key) + hints = self.format_hints(self, indent + 2, path) + if isinstance(value, dict): + result += "\n" + hints + result += self.format_properties(indent + 2, path) + else: + result += " -> %s\n" % (repr(value)) + result += hints + path.pop() + return result + + def format_hints(self, dhints, indent=0, path=[]): + dhints = self._obj["debug_hints"] + try: + for component in path: + dhints = dhints["properties"][component] + except KeyError: + return "" + + result = "" + for message in dhints["messages"]: + result += ' ' * indent + "%% modified in %s, lines %s:%s-%s:%s\n" % tuple(message[1:]) + return result + +class ObjectsFile: + def __init__(self, file): + self._file = file + + def __iter__(self): + fr = netstring.FileReader(self._file) + + while True: + try: + json_data = fr.readskip() + except EOFError: + break + if json_data == "": + break + yield DebugObject(json.loads(json_data)) diff --git a/python/icinga2/utils/netstring.py b/python/icinga2/utils/netstring.py new file mode 100644 index 00000000000..704c66f2642 --- /dev/null +++ b/python/icinga2/utils/netstring.py @@ -0,0 +1,305 @@ +#!/usr/bin/python +# netstring.py - Netstring encoding/decoding routines. +# Version 1.1 - July 2003 +# http://www.dlitz.net/software/python-netstring/ +# +# Copyright (c) 2003 Dwayne C. Litzenberger +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# HISTORY: +# +# Changes between 1.0 and 1.1: +# - Renamed Reader to BaseReader. Use FileReader and StringReader instead. +# - Added BaseReader.readskip() +# - Switched to saner stream reading semantics. Now the stream is not read +# until information is requested which requires it to be read. +# - Added split() +# + +from __future__ import generators +import StringIO + +"""Conversions to/from netstring format. + +The netstring format is defined in http://cr.yp.to/proto/netstrings.txt +(or http://www.dlitz.net/proto/netstrings-abnf.txt if you prefer ABNF) + +Classes: + + BaseReader (not to be used directly) + FileReader + StringReader + +Functions: + + dump + dumps + load + loads + split + +Misc variables: + + maxintlen - Maximum number of digits when reading integers + +""" + +__all__ = ['BaseReader', 'FileReader', 'StringReader', + 'dump', 'dumps', 'load', 'loads', 'split'] + +maxintlen = 999 # Maximum number of digits when reading integers + # This allows numbers up to 10**1000 - 1, which should + # be large enough for most applications. :-) + + +def dump(s, file): + """dump(s, file) -> None + +Writes the string s as a netstring to file. +""" + file.write(dumps(s)) + + +def dumps(s): + """dumps(s) -> string + +Encodes the string s as a netstring, and returns the result. +""" + return str(len(s)) + ":" + s + "," + + +def load(file, maxlen=None): + """load(file, maxlen=None) -> string + +Read a netstring from a file, and return the extracted netstring. + +If the parsed string would be longer than maxlen, OverflowError is raised. +""" + n = _readlen(file) + if maxlen is not None and n > maxlen: + raise OverflowError + retval = file.read(n) + #assert(len(retval) == n) + ch = file.read(1) + if ch == "": + raise EOFError + elif ch != ",": + raise ValueError + return retval + + +def loads(s, maxlen=None, returnUnparsed=False): + """loads(s, maxlen=None, returnUnparsed=False) -> string or (string, + string) + +Extract a netstring from a string. If returnUnparsed is false, return the +decoded netstring, otherwise return a tuple (parsed, unparsed) containing both +the parsed string and the remaining unparsed part of s. + +If the parsed string would be longer than maxlen, OverflowError is raised. +""" + f = StringIO.StringIO(s) + parsed = load(f, maxlen=maxlen) + if not returnUnparsed: + return parsed + unparsed = f.read() + return parsed, unparsed + + +def _readlen(file): + """_readlen(file) -> integer + +Read the initial "[length]:" of a netstring from file, and return the length. +""" + i = 0 + n = "" + ch = file.read(1) + while ch != ":": + if ch == "": + raise EOFError + elif not ch in "0123456789": + raise ValueError + n += ch + i += 1 + if i > maxintlen: + raise OverflowError + ch = file.read(1) + #assert(ch == ":") + return long(n) + + +def split(s): + """split(s) -> list of strings + +Return a list of the decoded netstrings in s. +""" + if s == "": + raise EOFError + retval = [] + unparsed = s + while unparsed != "": + parsed, unparsed = loads(unparsed, returnUnparsed=True) + retval.append(parsed) + return retval + + +class BaseReader: + """BaseReader(file, maxlen=None, blocksize=1024) -> BaseReader object + +Return a new BaseReader object. BaseReader allows reading a +netstring in blocks, instead of reading an netstring into memory at once. + +If BaseReader encounters a netstring which is larger than maxlen, it will return +OverflowError. BaseReader will also return ValueError if it encounters bad +formatting, or EOFError if an unexpected attempt is made to read beyond the +end of file. + +The state of BaseReader is undefined once any exception other than StopIteration +is raised. + +blocksize is the size of blocks to use when iterating over the BaseReader class. +You should not use BaseReader except when subclassing. Use FileReader or one +of the other *Reader classes instead. +""" + + def __init__(self, file, maxlen=None, blocksize=1024): + self._file = file + self._length = None + self._bytesleft = 0L + self._maxlen = maxlen + self._blocksize = blocksize + + def _readlen(self): + if self._length is None: + self._length = _readlen(self._file) + self._bytesleft = self._length + if self._maxlen is not None and self._length > self._maxlen: + raise OverflowError + # Handle the 0-byte case + if self._length == 0: + ch = self._file.read(1) + if ch == "": + raise EOFError + elif ch != ",": + raise ValueError + + def read(self, size=None): + """x.read([size]) -> string + +Works like .read. +""" + self._readlen() + if size is None or size > self._bytesleft: + size = self._bytesleft + if size == 0: + return "" + retval = self._file.read(size) + self._bytesleft -= len(retval) + if self._bytesleft == 0: + ch = self._file.read(1) + if ch == "": + raise EOFError + elif ch != ",": + raise ValueError + return retval + + def length(self): + """x.length() -> long + +Return the total length of the decoded string. +""" + self._readlen() + return self._length + + def bytesremaining(self): + """x.bytesremaining() -> long + +Return the number of decoded string bytes remaining to be read from the file. +""" + self._readlen() + return self._bytesleft + + def skip(self): + """x.skip() -> None + +Skip to the next netstring. +""" + self._readlen() + if self._bytesleft: + self._file.seek(self._bytesleft, 1) + ch = self._file.read(1) + if ch == "": + raise EOFError + elif ch != ",": + raise ValueError + self._bytesleft = 0L + self._length = None + + def readskip(self, size=None): + """x.readskip([size]) -> string + +Equivalent to x.read([size]); x.skip(). Returns whatever is returned by +x.read(). +""" + retval = self.read(size) + self.skip() + return retval + + def __iter__(self): + """x.__iter__() -> iterator + +Return a block of the decoded netstring. +""" + block = self.read(self._blocksize) + while block != "": + yield block + block = self.read(self._blocksize) + + def __len__(self): + """x.__len__() -> integer + +Return the total length of the decoded string. + +Note that this is limited to the maximum integer value. Use x.length() +wherever possible. +""" + return int(self.length()) + + +class FileReader(BaseReader): + """FileReader(file, ...) -> FileReader object + +Takes a file as input. See BaseReader.__doc__ for more information. +""" + pass + + +class StringReader(BaseReader): + """StringReader(s, ...) -> StringReader object + +Takes a string as input. See BaseReader.__doc__ for more information. +""" + def __init__(self, s, *args, **kwargs): + file = StringIO.StringIO(s) + return BaseReader.__init__(self, file, *args, **kwargs) + + +# vim:set tw=78 sw=4 ts=4 expandtab: diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 00000000000..97c20708711 --- /dev/null +++ b/python/setup.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +import os, re +from setuptools import setup, find_packages + +def get_icinga2_version(): + spec = open(os.path.join(os.path.dirname(__file__), '..', 'icinga2.spec')).read() + m = re.search('^Version: (.*)$', spec, re.MULTILINE) + if not m: + return None + return m.group(1) + +setup( + name = 'icinga2', + version = get_icinga2_version(), + packages = find_packages(), + entry_points = { + 'console_scripts': [ 'icinga2-list-objects=icinga2.commands.list_objects:main' ] + } +) + diff --git a/python/setup.py.cmake b/python/setup.py.cmake new file mode 100644 index 00000000000..ce8e1e04a51 --- /dev/null +++ b/python/setup.py.cmake @@ -0,0 +1,20 @@ +#!/usr/bin/env python +import os, re +from setuptools import setup, find_packages + +def get_icinga2_version(): + spec = open(os.path.join('@PROJECT_SOURCE_DIR@', 'icinga2.spec')).read() + m = re.search('^Version: (.*)$', spec, re.MULTILINE) + if not m: + return None + return m.group(1) + +setup( + name = 'icinga2', + version = get_icinga2_version(), + packages = find_packages(), + entry_points = { + 'console_scripts': [ 'icinga2-list-objects=icinga2.commands.list_objects:main' ] + } +) + diff --git a/third-party/cmake/PythonSetup.cmake b/third-party/cmake/PythonSetup.cmake new file mode 100644 index 00000000000..9042eaec373 --- /dev/null +++ b/third-party/cmake/PythonSetup.cmake @@ -0,0 +1,215 @@ +# Copyright: 2004 Martin F. Krafft +# 2008 Martin Schreiber +# 2012-2013 Sebastian Ramacher +# License: Artistic-2.0 +# +# License: Artistic-2.0 +# Copyright (c) 2000-2006, The Perl Foundation. +# http://www.perlfoundation.org/artistic_license_2_0 +# . +# Everyone is permitted to copy and distribute verbatim copies of this +# license document, but changing it is not allowed. +# . +# Preamble +# . +# This license establishes the terms under which a given free software +# Package may be copied, modified, distributed, and/or redistributed. +# The intent is that the Copyright Holder maintains some artistic +# control over the development of that Package while still keeping the +# Package available as open source and free software. +# . +# You are always permitted to make arrangements wholly outside of this +# license directly with the Copyright Holder of a given Package. If the +# terms of this license do not permit the full use that you propose to +# make of the Package, you should contact the Copyright Holder and seek +# a different licensing arrangement. +# . +# Definitions +# . +# "Copyright Holder" means the individual(s) or organization(s) named in +# the copyright notice for the entire Package. +# . +# "Contributor" means any party that has contributed code or other +# material to the Package, in accordance with the Copyright Holder's +# procedures. +# . +# "You" and "your" means any person who would like to copy, distribute, +# or modify the Package. +# . +# "Package" means the collection of files distributed by the Copyright +# Holder, and derivatives of that collection and/or of those files. A +# given Package may consist of either the Standard Version, or a +# Modified Version. +# . +# "Distribute" means providing a copy of the Package or making it +# accessible to anyone else, or in the case of a company or +# organization, to others outside of your company or organization. +# . +# "Distributor Fee" means any fee that you charge for Distributing this +# Package or providing support for this Package to another party. It +# does not mean licensing fees. +# . +# "Standard Version" refers to the Package if it has not been modified, +# or has been modified only in ways explicitly requested by the +# Copyright Holder. +# . +# "Modified Version" means the Package, if it has been changed, and such +# changes were not explicitly requested by the Copyright Holder. +# . +# "Original License" means this Artistic License as Distributed with the +# Standard Version of the Package, in its current version or as it may +# be modified by The Perl Foundation in the future. +# . +# "Source" form means the source code, documentation source, and +# configuration files for the Package. +# . +# "Compiled" form means the compiled bytecode, object code, binary, or +# any other form resulting from mechanical transformation or translation +# of the Source form. +# . +# Permission for Use and Modification Without Distribution +# . +# (1) You are permitted to use the Standard Version and create and use +# Modified Versions for any purpose without restriction, provided that +# you do not Distribute the Modified Version. +# . +# Permissions for Redistribution of the Standard Version +# . +# (2) You may Distribute verbatim copies of the Source form of the +# Standard Version of this Package in any medium without restriction, +# either gratis or for a Distributor Fee, provided that you duplicate +# all of the original copyright notices and associated disclaimers. At +# your discretion, such verbatim copies may or may not include a +# Compiled form of the Package. +# . +# (3) You may apply any bug fixes, portability changes, and other +# modifications made available from the Copyright Holder. The resulting +# Package will still be considered the Standard Version, and as such +# will be subject to the Original License. +# . +# Distribution of Modified Versions of the Package as Source +# . +# (4) You may Distribute your Modified Version as Source (either gratis +# or for a Distributor Fee, and with or without a Compiled form of the +# Modified Version) provided that you clearly document how it differs +# from the Standard Version, including, but not limited to, documenting +# any non-standard features, executables, or modules, and provided that +# you do at least ONE of the following: +# . +# (a) make the Modified Version available to the Copyright Holder of the +# Standard Version, under the Original License, so that the Copyright +# Holder may include your modifications in the Standard Version. (b) +# ensure that installation of your Modified Version does not prevent the +# user installing or running the Standard Version. In addition, the +# Modified Version must bear a name that is different from the name of +# the Standard Version. (c) allow anyone who receives a copy of the +# Modified Version to make the Source form of the Modified Version +# available to others under (i) the Original License or (ii) a license +# that permits the licensee to freely copy, modify and redistribute the +# Modified Version using the same licensing terms that apply to the copy +# that the licensee received, and requires that the Source form of the +# Modified Version, and of any works derived from it, be made freely +# available in that license fees are prohibited but Distributor Fees are +# allowed. +# . +# Distribution of Compiled Forms of the Standard Version or Modified +# Versions without the Source +# . +# (5) You may Distribute Compiled forms of the Standard Version without +# the Source, provided that you include complete instructions on how to +# get the Source of the Standard Version. Such instructions must be +# valid at the time of your distribution. If these instructions, at any +# time while you are carrying out such distribution, become invalid, you +# must provide new instructions on demand or cease further distribution. +# If you provide valid instructions or cease distribution within thirty +# days after you become aware that the instructions are invalid, then +# you do not forfeit any of your rights under this license. +# . +# (6) You may Distribute a Modified Version in Compiled form without the +# Source, provided that you comply with Section 4 with respect to the +# Source of the Modified Version. +# . +# Aggregating or Linking the Package +# . +# (7) You may aggregate the Package (either the Standard Version or +# Modified Version) with other packages and Distribute the resulting +# aggregation provided that you do not charge a licensing fee for the +# Package. Distributor Fees are permitted, and licensing fees for other +# components in the aggregation are permitted. The terms of this license +# apply to the use and Distribution of the Standard or Modified Versions +# as included in the aggregation. +# . +# (8) You are permitted to link Modified and Standard Versions with +# other works, to embed the Package in a larger work of your own, or to +# build stand-alone binary or bytecode versions of applications that +# include the Package, and Distribute the result without restriction, +# provided the result does not expose a direct interface to the Package. +# . +# Items That are Not Considered Part of a Modified Version +# . +# (9) Works (including, but not limited to, modules and scripts) that +# merely extend or make use of the Package, do not, by themselves, cause +# the Package to be a Modified Version. In addition, such works are not +# considered parts of the Package itself, and are not subject to the +# terms of this license. +# . +# General Provisions +# . +# (10) Any use, modification, and distribution of the Standard or +# Modified Versions is governed by this Artistic License. By using, +# modifying or distributing the Package, you accept this license. Do not +# use, modify, or distribute the Package, if you do not accept this +# license. +# . +# (11) If your Modified Version has been derived from a Modified Version +# made by someone other than you, you are nevertheless required to +# ensure that your Modified Version complies with the requirements of +# this license. +# . +# (12) This license does not grant you the right to use any trademark, +# service mark, tradename, or logo of the Copyright Holder. +# . +# (13) This license includes the non-exclusive, worldwide, +# free-of-charge patent license to make, have made, use, offer to sell, +# sell, import and otherwise transfer the Package with respect to any +# patent claims licensable by the Copyright Holder that are necessarily +# infringed by the Package. If you institute patent litigation +# (including a cross-claim or counterclaim) against any party alleging +# that the Package constitutes direct or contributory patent +# infringement, then this Artistic License to you shall terminate on the +# date that such litigation is filed. +# . +# (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT +# HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED +# WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +# PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT +# PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT +# HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE +# OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This is a ugly workaround to be able to pass DESTDIR as --root to setup.py. +# cmake expands any occurence of $ENV{foo} with the value of foo while runing +# cmake and not while running make afterwards. + +SET(PYTHON_EXECUTABLE "" CACHE FORCE "Python executable") +SET(PREFIX ${CMAKE_INSTALL_PREFIX} CACHE FORCE "cmake install prefix") +SET(WDIR "" CACHE FORCE "working directory") +SET(SETUP_PY "" CACHE FORCE "setup.py path") +SET(EXTRA_ARGS $ENV{SETUP_PY_EXTRA_ARGS} CACHE FORCE "extra arguments for setup.py") + +SET(INSTALL_ROOT $ENV{DESTDIR}) +IF(INSTALL_ROOT) + SET(INSTALL_ROOT_ARGS "--root=$ENV{DESTDIR}") +ELSE(INSTALL_ROOT) + SET(INSTALL_ROOT_ARGS "") +ENDIF(INSTALL_ROOT) + +EXECUTE_PROCESS( + COMMAND ${PYTHON_EXECUTABLE} + ${SETUP_PY} + install + --prefix=${PREFIX} + ${INSTALL_ROOT_ARGS} + ${EXTRA_ARGS} + WORKING_DIRECTORY ${WDIR})