Refactored the python bindings into multiple modules.
The existing module has been split into two separate ones:
- mesos.interface - This contains the stub implementations for the
Executor/Scheduler as well as the protobufs.
- mesos.native - The old _mesos module.
There is also a base metapackage `mesos` that allows a potential `pip
install mesos` to correctly install everything required. While
mesos.interface can now be uploaded to the cheeseshop, mesos.native
has not changed and will need some more work first.
Review: https://reviews.apache.org/r/23224
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c5a68be1
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c5a68be1
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c5a68be1
Branch: refs/heads/master
Commit: c5a68be12a68cba407d9e3364f6f8f405cbe7d79
Parents: 3047bbe
Author: Thomas Rampelberg <[email protected]>
Authored: Thu Jul 31 21:11:26 2014 -0700
Committer: Benjamin Hindman <[email protected]>
Committed: Thu Jul 31 22:45:26 2014 -0700
----------------------------------------------------------------------
Makefile.am | 8 +-
configure.ac | 28 +
docs/upgrades.md | 5 +
mpi/mpiexec-mesos.in | 24 +-
mpi/mpiexec-mesos.py | 9 +-
src/Makefile.am | 98 +--
src/examples/python/test-containerizer.in | 25 +-
src/examples/python/test-executor.in | 25 +-
src/examples/python/test-framework.in | 25 +-
src/examples/python/test_containerizer.py | 5 +-
src/examples/python/test_executor.py | 13 +-
src/examples/python/test_framework.py | 11 +-
src/python/interface/setup.py.in | 35 +
src/python/interface/src/mesos/__init__.py | 6 +
.../interface/src/mesos/interface/__init__.py | 347 ++++++++++
src/python/native/ext_modules.py.in | 131 ++++
.../native/mesos_executor_driver_impl.cpp | 349 ----------
.../native/mesos_executor_driver_impl.hpp | 105 ---
.../native/mesos_scheduler_driver_impl.cpp | 634 -------------------
.../native/mesos_scheduler_driver_impl.hpp | 125 ----
src/python/native/module.cpp | 102 ---
src/python/native/module.hpp | 138 ----
src/python/native/proxy_executor.cpp | 275 --------
src/python/native/proxy_executor.hpp | 66 --
src/python/native/proxy_scheduler.cpp | 386 -----------
src/python/native/proxy_scheduler.hpp | 74 ---
src/python/native/setup.py.in | 38 ++
src/python/native/src/mesos/__init__.py | 6 +
src/python/native/src/mesos/native/__init__.py | 21 +
.../mesos/native/mesos_executor_driver_impl.cpp | 349 ++++++++++
.../mesos/native/mesos_executor_driver_impl.hpp | 105 +++
.../native/mesos_scheduler_driver_impl.cpp | 634 +++++++++++++++++++
.../native/mesos_scheduler_driver_impl.hpp | 125 ++++
src/python/native/src/mesos/native/module.cpp | 102 +++
src/python/native/src/mesos/native/module.hpp | 138 ++++
.../native/src/mesos/native/proxy_executor.cpp | 275 ++++++++
.../native/src/mesos/native/proxy_executor.hpp | 66 ++
.../native/src/mesos/native/proxy_scheduler.cpp | 386 +++++++++++
.../native/src/mesos/native/proxy_scheduler.hpp | 74 +++
src/python/protocol/setup.py.in | 35 +
src/python/protocol/src/mesos/__init__.py | 6 +
.../protocol/src/mesos/protocol/__init__.py | 15 +
src/python/setup.py.in | 186 ++----
src/python/src/mesos.py | 361 -----------
src/python/src/mesos/__init__.py | 6 +
45 files changed, 3123 insertions(+), 2854 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/Makefile.am
----------------------------------------------------------------------
diff --git a/Makefile.am b/Makefile.am
index b91d8cf..e4ffa35 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,12 +27,14 @@ PHONY_TARGETS =
# Since we generate several files in src/ with config.status, make
# sure they're regenerated before we recurse into the src directory.
-all-recursive: src/python/setup.py src/java/mesos.pom
-
+all-recursive: src/python/setup.py \
+ src/python/interface/setup.py \
+ src/python/native/setup.py \
+ src/java/mesos.pom
# Standard stuff.
EXTRA_DIST += bootstrap LICENSE NOTICE README.md \
- support/atexit.sh support/colors.sh
+ support/atexit.sh support/colors.sh
# MPI framework.
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index e747208..a9cc6df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -822,6 +822,31 @@ There are two possible workarounds for this issue:
-------------------------------------------------------------------])])
])
+ AC_MSG_CHECKING([for an old installation of the Mesos egg (before 0.20.0)])
+
+ $PYTHON -c "import mesos; mesos._mesos" &> /dev/null
+
+ if test $? = 0; then
+ pymodulelocation=`python -c \
+ "import mesos; import os; print os.path.dirname(mesos.__path__[[0]])" \
+ 2> /dev/null`
+ fi
+
+ AS_IF([test -z "$pymodulelocation"],
+ [AC_MSG_RESULT([no])],
+ [AC_MSG_ERROR([yes
+-------------------------------------------------------------------
+It appears that you currently have a native Python egg installed
+from a version before 0.20.0. This conflicts with the egg in this
+version.
+
+There are two possible workarounds for this issue:
+ 1. Disable Python bindings by configuring with --disable-python.
+ 2. Uninstall the legacy egg from your Python installation. This
+ might require you doing:
+ rm -rf $pymodulelocation
+-------------------------------------------------------------------])])
+
# Determine how the generated Python egg's will get named, used in
# the Makefile to keep the targets from being rerun.
PYTHON_EGG_POSTFIX=`$PYTHON -c \
@@ -841,6 +866,9 @@ There are two possible workarounds for this issue:
AC_CONFIG_FILES([src/examples/python/test-containerizer],
[chmod +x src/examples/python/test-containerizer])
AC_CONFIG_FILES([src/python/setup.py])
+ AC_CONFIG_FILES([src/python/interface/setup.py])
+ AC_CONFIG_FILES([src/python/native/ext_modules.py])
+ AC_CONFIG_FILES([src/python/native/setup.py])
# When clang is being used, make sure that the distutils python-
# config cflags extraction does not cause build errors (MESOS-1079).
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/docs/upgrades.md
----------------------------------------------------------------------
diff --git a/docs/upgrades.md b/docs/upgrades.md
index 919f010..2d518be 100644
--- a/docs/upgrades.md
+++ b/docs/upgrades.md
@@ -5,6 +5,11 @@ layout: documentation
# Upgrading Mesos
This document serves as a guide for users who wish to upgrade an existing
mesos cluster. Some versions require particular upgrade techniques when
upgrading a running cluster. Some upgrades will have incompatible changes.
+## Upgrading from 0.19.x to 0.20.x.
+
+* Python bindings have changed their structure. There are now sub-modules
which allow you to use either the interfaces and/or the native driver.
+ - `import mesos.native` for the native drivers
+ - `import mesos.interface` for the stub implementations and protobufs
## Upgrading from 0.18.x to 0.19.x.
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/mpi/mpiexec-mesos.in
----------------------------------------------------------------------
diff --git a/mpi/mpiexec-mesos.in b/mpi/mpiexec-mesos.in
index da0733f..8812ee2 100644
--- a/mpi/mpiexec-mesos.in
+++ b/mpi/mpiexec-mesos.in
@@ -29,11 +29,25 @@ test ! -e ${PROTOBUF_EGG} && \
echo "${RED}Failed to find ${PROTOBUF_EGG}${NORMAL}" && \
exit 1
-MESOS_EGG=`echo ${MESOS_BUILD_DIR}/src/python/dist/mesos*.egg`
+MESOS_EGGS=""
+for egg in interface native; do
+ base_dir="${MESOS_BUILD_DIR}/src/python/${egg}/dist/"
+ egg_path="${base_dir}mesos.${egg}-@PACKAGE_VERSION@"
-test ! -e ${MESOS_EGG} && \
- echo "${RED}Failed to find ${MESOS_EGG}${NORMAL}" && \
- exit 1
+ if [[ ${egg} == "native" ]]; then
+ egg_path+="@PYTHON_EGG_POSTFIX@"
+ else
+ egg_path+="@PYTHON_EGG_PUREPY_POSTFIX@"
+ fi
+
+ egg_path+=".egg"
+
+ test ! -e ${egg_path} && \
+ echo "${RED}Failed to find ${egg_path}${NORMAL}" && \
+ exit 1
+
+ MESOS_EGGS+="${egg_path}:"
+done
SCRIPT=${MESOS_SOURCE_DIR}/mpi/mpiexec-mesos.py
@@ -41,5 +55,5 @@ test ! -e ${SCRIPT} && \
echo "${RED}Failed to find ${SCRIPT}${NORMAL}" && \
exit 1
-PYTHONPATH="${DISTRIBUTE_EGG}:${MESOS_EGG}:${PROTOBUF_EGG}" \
+PYTHONPATH="${DISTRIBUTE_EGG}:${PROTOBUF_EGG}:${MESOS_EGGS}" \
exec ${PYTHON} ${SCRIPT} "${@}"
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/mpi/mpiexec-mesos.py
----------------------------------------------------------------------
diff --git a/mpi/mpiexec-mesos.py b/mpi/mpiexec-mesos.py
index 0ab5016..d86c85b 100755
--- a/mpi/mpiexec-mesos.py
+++ b/mpi/mpiexec-mesos.py
@@ -1,7 +1,8 @@
#!/usr/bin/env python
-import mesos
-import mesos_pb2
+import mesos.interface
+import mesos.native
+from mesos.interface import mesos_pb2
import os
import sys
import time
@@ -36,7 +37,7 @@ def mpiexec():
call([MPICH2PATH + 'mpdallexit', MPD_PID])
-class MPIScheduler(mesos.Scheduler):
+class MPIScheduler(mesos.interface.Scheduler):
def __init__(self, options, ip, port):
self.mpdsLaunched = 0
@@ -209,7 +210,7 @@ if __name__ == "__main__":
else:
framework.name = "MPI: %s" % MPI_PROGRAM[0]
- driver = mesos.MesosSchedulerDriver(
+ driver = mesos.native.MesosSchedulerDriver(
scheduler,
framework,
args[0])
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index b660d91..c7ed168 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -135,8 +135,8 @@ JAVA_PROTOS =
\
java/generated/org/apache/mesos/containerizer/Protos.java
PYTHON_PROTOS =
\
- python/src/mesos_pb2.py \
- python/src/containerizer_pb2.py
+ python/interface/src/mesos/interface/mesos_pb2.py \
+ python/interface/src/mesos/interface/containerizer_pb2.py
BUILT_SOURCES += $(CXX_PROTOS) $(JAVA_PROTOS) $(PYTHON_PROTOS)
CLEANFILES += $(CXX_PROTOS) $(JAVA_PROTOS) $(PYTHON_PROTOS)
@@ -198,19 +198,19 @@ java/generated/org/apache/mesos/scheduler/Protos.java:
$(SCHEDULER_PROTO)
$(MKDIR_P) $(@D)
$(PROTOC) $(PROTOCFLAGS) --java_out=java/generated $^
-python/src/mesos_pb2.py: $(MESOS_PROTO)
+python/interface/src/mesos/interface/mesos_pb2.py: $(MESOS_PROTO)
$(MKDIR_P) $(@D)
- $(PROTOC) $(PROTOCFLAGS) --python_out=python/src $^
+ $(PROTOC) $(PROTOCFLAGS)
--python_out=python/interface/src/mesos/interface $^
-python/src/containerizer_pb2.py: $(CONTAINERIZER_PROTO)
+python/interface/src/mesos/interface/containerizer_pb2.py:
$(CONTAINERIZER_PROTO)
$(MKDIR_P) $(@D)
$(PROTOC) -I$(top_srcdir)/include/mesos/containerizer \
- $(PROTOCFLAGS) --python_out=python/src $^
+ $(PROTOCFLAGS)
--python_out=python/interface/src/mesos/interface $^
-python/src/scheduler_pb2.py: $(SCHEDULER_PROTO)
+python/interface/src/mesos/interface/scheduler_pb2.py: $(SCHEDULER_PROTO)
$(MKDIR_P) $(@D)
$(PROTOC) -I$(top_srcdir)/include/mesos/scheduler \
- $(PROTOCFLAGS) --python_out=python/src $^
+ $(PROTOCFLAGS)
--python_out=python/interface/src/mesos/interface $^
# We even use a convenience library for most of Mesos so that we can
# exclude third party libraries so setuptools/distribute can build a
@@ -892,16 +892,24 @@ PHONY_TARGETS += clean-java
# Python files listed outside HAS_PYTHON so they are included with the
# distribution unconditionally.
-EXTRA_DIST += python/src/mesos.py \
- python/native/mesos_executor_driver_impl.cpp \
- python/native/mesos_executor_driver_impl.hpp \
- python/native/mesos_scheduler_driver_impl.cpp \
- python/native/mesos_scheduler_driver_impl.hpp \
- python/native/module.cpp python/native/module.hpp \
- python/native/proxy_executor.cpp \
- python/native/proxy_executor.hpp \
- python/native/proxy_scheduler.cpp \
- python/native/proxy_scheduler.hpp
+PYTHON_SOURCE =
\
+ python/src/mesos/__init__.py
\
+ python/interface/src/mesos/__init__.py
\
+ python/interface/src/mesos/interface/__init__.py
\
+ python/native/src/mesos/__init__.py
\
+ python/native/src/mesos/native/__init__.py
\
+ python/native/src/mesos/native/mesos_executor_driver_impl.cpp
\
+ python/native/src/mesos/native/mesos_executor_driver_impl.hpp
\
+ python/native/src/mesos/native/mesos_scheduler_driver_impl.cpp
\
+ python/native/src/mesos/native/mesos_scheduler_driver_impl.hpp
\
+ python/native/src/mesos/native/module.cpp
\
+ python/native/src/mesos/native/module.hpp
\
+ python/native/src/mesos/native/proxy_executor.cpp
\
+ python/native/src/mesos/native/proxy_executor.hpp
\
+ python/native/src/mesos/native/proxy_scheduler.cpp
\
+ python/native/src/mesos/native/proxy_scheduler.hpp
+
+EXTRA_DIST += $(PYTHON_SOURCE)
if HAS_PYTHON
# Used for building Python eggs.
@@ -921,7 +929,7 @@ $(PROTOBUF_EGG):
CLEANFILES += $(PROTOBUF_EGG)
-# This builds a Python egg against libmesos_no_3rdparty.a that is
+# This builds the mesos.native egg against libmesos_no_3rdparty.a that is
# self-contained. It currently depends on the libraries in 3rdparty
# being built as .a's. (If this is changed, the setup.py will need to
# be edited).
@@ -936,44 +944,40 @@ CLEANFILES += $(PROTOBUF_EGG)
# system versions of our dependencies (since we won't be able to
# create a standalone egg anyways).
-MESOS_EGG = python/dist/mesos-$(PACKAGE_VERSION)$(PYTHON_EGG_POSTFIX).egg
+PHONY_TARGETS += $(PYTHON_SOURCE)
-$(MESOS_EGG): python/setup.py $(srcdir)/python/src/mesos.py \
- $(PYTHON_PROTOS) libmesos_no_3rdparty.la \
- $(PROTOBUF_EGG)
- @echo "Building Mesos Python egg ..."
- @if test "$(top_srcdir)" != "$(top_builddir)"; then \
- $(MKDIR_P) python/src; \
- cp -pf $(srcdir)/python/src/mesos.py python/src; \
- fi
- @LIBS="$(LIBS)" CC="$(CC)" CXX="$(CXX)" \
- CPPFLAGS="$(PYTHON_CPPFLAGS)" CFLAGS="$(PYTHON_CFLAGS)" \
- LDFLAGS="$(PYTHON_LDFLAGS)" \
- PYTHONPATH=$(DISTRIBUTE_EGG) $(PYTHON) python/setup.py bdist_egg
+$(PYTHON_SOURCE):
+ test "$(top_srcdir)" = "$(top_builddir)" ||
\
+ ($(MKDIR_P) $(@D) && cp -pf $(srcdir)/$@ $@)
-CLEANFILES += $(MESOS_EGG) python/build/temp.*/native/*.o python/build/lib.*/*
+MESOS_EGGS =
\
+ python/dist/mesos-$(PACKAGE_VERSION)$(PYTHON_EGG_PUREPY_POSTFIX).egg
\
+
python/interface/dist/mesos.interface-$(PACKAGE_VERSION)$(PYTHON_EGG_PUREPY_POSTFIX).egg
\
+
python/native/dist/mesos.native-$(PACKAGE_VERSION)$(PYTHON_EGG_POSTFIX).egg
+
+$(MESOS_EGGS):
\
+ $(PYTHON_PROTOS)
\
+ $(PYTHON_SOURCE)
\
+ libmesos_no_3rdparty.la
\
+ $(PROTOBUF_EGG)
+ @cd `echo $@ | awk -F"dist" '{print $$1}'` &&
\
+ LIBS="$(LIBS)" CC="$(CC)" CXX="$(CXX)"
\
+ CFLAGS="$(PYTHON_CFLAGS)" CPPFLAGS="$(PYTHON_CPPFLAGS)"
\
+ LDFLAGS="$(PYTHON_LDFLAGS)"
\
+ PYTHONPATH=$(DISTRIBUTE_EGG) $(PYTHON) setup.py bdist_egg
+
+CLEANFILES += $(MESOS_EGGS) python/*/build python/*/dist $(PYTHON_SOURCE)
# Make sure the egg gets built via 'make all'.
-all-local: $(MESOS_EGG)
+all-local: $(MESOS_EGGS)
endif # HAS_PYTHON
-# Note that to clean up the copied Python files we have to 'chmod u+w
-# python/native' because creating a distribution can eliminate write
-# permissions for the owner which are conserved even after we 'cp -p'
-# so we won't be able to delete the files until we update permissions.
-#
-# We remove mesos-*.egg here to make sure any older versions of the
-# egg or versions for different architectures are removed.
clean-python:
- test "$(top_srcdir)" = "$(top_builddir)" || \
- (chmod -R u+w python/native; \
- rm -rf python/src/mesos.py python/native)
- -rm -rf python/src/mesos.egg-info python/build
- -rm -f python/dist/mesos-*.egg
+ find python -name "build" -o -name "dist" -o -name "*.pyc"
\
+ -o -name "*.egg-info" | xargs rm -rf
PHONY_TARGETS += clean-python
-
# Test (make check) binaries.
check_PROGRAMS += low-level-scheduler-libprocess
low_level_scheduler_libprocess_SOURCES =
examples/low_level_scheduler_libprocess.cpp
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/examples/python/test-containerizer.in
----------------------------------------------------------------------
diff --git a/src/examples/python/test-containerizer.in
b/src/examples/python/test-containerizer.in
index 569519b..f71828d 100644
--- a/src/examples/python/test-containerizer.in
+++ b/src/examples/python/test-containerizer.in
@@ -30,12 +30,25 @@ test ! -e ${PROTOBUF_EGG} && \
echo "${RED}Failed to find ${PROTOBUF_EGG}${NORMAL}" && \
exit 1
-MESOS_EGG=${MESOS_BUILD_DIR}/src/python/dist/
-MESOS_EGG+=mesos-@PACKAGE_VERSION@@[email protected]
+MESOS_EGGS=""
+for egg in interface native; do
+ base_dir="${MESOS_BUILD_DIR}/src/python/${egg}/dist/"
+ egg_path="${base_dir}mesos.${egg}-@PACKAGE_VERSION@"
-test ! -e ${MESOS_EGG} && \
- echo "${RED}Failed to find ${MESOS_EGG}${NORMAL}" && \
- exit 1
+ if [[ ${egg} == "native" ]]; then
+ egg_path+="@PYTHON_EGG_POSTFIX@"
+ else
+ egg_path+="@PYTHON_EGG_PUREPY_POSTFIX@"
+ fi
+
+ egg_path+=".egg"
+
+ test ! -e ${egg_path} && \
+ echo "${RED}Failed to find ${egg_path}${NORMAL}" && \
+ exit 1
+
+ MESOS_EGGS+="${egg_path}:"
+done
SCRIPT=${MESOS_SOURCE_DIR}/src/examples/python/test_containerizer.py
@@ -43,5 +56,5 @@ test ! -e ${SCRIPT} && \
echo "${RED}Failed to find ${SCRIPT}${NORMAL}" && \
exit 1
-PYTHONPATH="${DISTRIBUTE_EGG}:${MESOS_EGG}:${PROTOBUF_EGG}" \
+PYTHONPATH="${DISTRIBUTE_EGG}:${PROTOBUF_EGG}:${MESOS_EGGS}" \
exec ${PYTHON} ${SCRIPT} "${@}"
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/examples/python/test-executor.in
----------------------------------------------------------------------
diff --git a/src/examples/python/test-executor.in
b/src/examples/python/test-executor.in
index 7e8875f..b22e7a7 100644
--- a/src/examples/python/test-executor.in
+++ b/src/examples/python/test-executor.in
@@ -30,12 +30,25 @@ test ! -e ${PROTOBUF_EGG} && \
echo "${RED}Failed to find ${PROTOBUF_EGG}${NORMAL}" && \
exit 1
-MESOS_EGG=${MESOS_BUILD_DIR}/src/python/dist/
-MESOS_EGG+=mesos-@PACKAGE_VERSION@@[email protected]
+MESOS_EGGS=""
+for egg in interface native; do
+ base_dir="${MESOS_BUILD_DIR}/src/python/${egg}/dist/"
+ egg_path="${base_dir}mesos.${egg}-@PACKAGE_VERSION@"
-test ! -e ${MESOS_EGG} && \
- echo "${RED}Failed to find ${MESOS_EGG}${NORMAL}" && \
- exit 1
+ if [[ ${egg} == "native" ]]; then
+ egg_path+="@PYTHON_EGG_POSTFIX@"
+ else
+ egg_path+="@PYTHON_EGG_PUREPY_POSTFIX@"
+ fi
+
+ egg_path+=".egg"
+
+ test ! -e ${egg_path} && \
+ echo "${RED}Failed to find ${egg_path}${NORMAL}" && \
+ exit 1
+
+ MESOS_EGGS+="${egg_path}:"
+done
SCRIPT=${MESOS_SOURCE_DIR}/src/examples/python/test_executor.py
@@ -43,5 +56,5 @@ test ! -e ${SCRIPT} && \
echo "${RED}Failed to find ${SCRIPT}${NORMAL}" && \
exit 1
-PYTHONPATH="${DISTRIBUTE_EGG}:${MESOS_EGG}:${PROTOBUF_EGG}" \
+PYTHONPATH="${DISTRIBUTE_EGG}:${PROTOBUF_EGG}:${MESOS_EGGS}" \
exec ${PYTHON} ${SCRIPT} "${@}"
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/examples/python/test-framework.in
----------------------------------------------------------------------
diff --git a/src/examples/python/test-framework.in
b/src/examples/python/test-framework.in
index c4683b9..64fb1dd 100644
--- a/src/examples/python/test-framework.in
+++ b/src/examples/python/test-framework.in
@@ -30,12 +30,25 @@ test ! -e ${PROTOBUF_EGG} && \
echo "${RED}Failed to find ${PROTOBUF_EGG}${NORMAL}" && \
exit 1
-MESOS_EGG=${MESOS_BUILD_DIR}/src/python/dist/
-MESOS_EGG+=mesos-@PACKAGE_VERSION@@[email protected]
+MESOS_EGGS=""
+for egg in interface native; do
+ base_dir="${MESOS_BUILD_DIR}/src/python/${egg}/dist/"
+ egg_path="${base_dir}mesos.${egg}-@PACKAGE_VERSION@"
-test ! -e ${MESOS_EGG} && \
- echo "${RED}Failed to find ${MESOS_EGG}${NORMAL}" && \
- exit 1
+ if [[ ${egg} == "native" ]]; then
+ egg_path+="@PYTHON_EGG_POSTFIX@"
+ else
+ egg_path+="@PYTHON_EGG_PUREPY_POSTFIX@"
+ fi
+
+ egg_path+=".egg"
+
+ test ! -e ${egg_path} && \
+ echo "${RED}Failed to find ${egg_path}${NORMAL}" && \
+ exit 1
+
+ MESOS_EGGS+="${egg_path}:"
+done
SCRIPT=${MESOS_SOURCE_DIR}/src/examples/python/test_framework.py
@@ -47,5 +60,5 @@ test ! -e ${SCRIPT} && \
# framework is able to find the executor.
cd `dirname ${0}`
-PYTHONPATH="${DISTRIBUTE_EGG}:${MESOS_EGG}:${PROTOBUF_EGG}" \
+PYTHONPATH="${DISTRIBUTE_EGG}:${PROTOBUF_EGG}:${MESOS_EGGS}" \
exec ${PYTHON} ${SCRIPT} "${@}"
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/examples/python/test_containerizer.py
----------------------------------------------------------------------
diff --git a/src/examples/python/test_containerizer.py
b/src/examples/python/test_containerizer.py
index c65d891..8e154b0 100644
--- a/src/examples/python/test_containerizer.py
+++ b/src/examples/python/test_containerizer.py
@@ -40,10 +40,9 @@ import sys
import struct
import time
import google
-import mesos
-import mesos_pb2
-import containerizer_pb2
+from mesos.interface import containerizer_pb2
+from mesos.interface import mesos_pb2
# Render a string describing how to use this script.
def use(argv0, methods):
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/examples/python/test_executor.py
----------------------------------------------------------------------
diff --git a/src/examples/python/test_executor.py
b/src/examples/python/test_executor.py
index 065b50a..f29da95 100755
--- a/src/examples/python/test_executor.py
+++ b/src/examples/python/test_executor.py
@@ -7,9 +7,9 @@
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,10 +20,11 @@ import sys
import threading
import time
-import mesos
-import mesos_pb2
+import mesos.interface
+from mesos.interface import mesos_pb2
+import mesos.native
-class MyExecutor(mesos.Executor):
+class MyExecutor(mesos.interface.Executor):
def launchTask(self, driver, task):
# Create a thread to run the task. Tasks should always be run in new
# threads or processes, rather than inside launchTask itself.
@@ -54,5 +55,5 @@ class MyExecutor(mesos.Executor):
if __name__ == "__main__":
print "Starting executor"
- driver = mesos.MesosExecutorDriver(MyExecutor())
+ driver = mesos.native.MesosExecutorDriver(MyExecutor())
sys.exit(0 if driver.run() == mesos_pb2.DRIVER_STOPPED else 1)
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/examples/python/test_framework.py
----------------------------------------------------------------------
diff --git a/src/examples/python/test_framework.py
b/src/examples/python/test_framework.py
index fce090f..75ca509 100755
--- a/src/examples/python/test_framework.py
+++ b/src/examples/python/test_framework.py
@@ -20,15 +20,16 @@ import os
import sys
import time
-import mesos
-import mesos_pb2
+import mesos.interface
+from mesos.interface import mesos_pb2
+import mesos.native
TOTAL_TASKS = 5
TASK_CPUS = 1
TASK_MEM = 32
-class TestScheduler(mesos.Scheduler):
+class TestScheduler(mesos.interface.Scheduler):
def __init__(self, executor):
self.executor = executor
self.taskData = {}
@@ -153,7 +154,7 @@ if __name__ == "__main__":
framework.principal = os.getenv("DEFAULT_PRINCIPAL")
- driver = mesos.MesosSchedulerDriver(
+ driver = mesos.native.MesosSchedulerDriver(
TestScheduler(executor),
framework,
sys.argv[1],
@@ -161,7 +162,7 @@ if __name__ == "__main__":
else:
framework.principal = "test-framework-python"
- driver = mesos.MesosSchedulerDriver(
+ driver = mesos.native.MesosSchedulerDriver(
TestScheduler(executor),
framework,
sys.argv[1])
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/python/interface/setup.py.in
----------------------------------------------------------------------
diff --git a/src/python/interface/setup.py.in b/src/python/interface/setup.py.in
new file mode 100644
index 0000000..afcaf7a
--- /dev/null
+++ b/src/python/interface/setup.py.in
@@ -0,0 +1,35 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+config = {
+ 'name': 'mesos.interface',
+ 'version': '@PACKAGE_VERSION@',
+ 'description': 'Mesos interfaces',
+ 'author': 'Apache Mesos',
+ 'author_email': '[email protected]',
+ 'url': 'http://pypi.python.org/pypi/mesos.interface',
+ 'namespace_packages': [ 'mesos' ],
+ 'packages': [ 'mesos', 'mesos.interface' ],
+ 'package_dir': { '': 'src' },
+ 'install_requires': [ 'protobuf>=2.5.0,<3' ],
+ 'license': 'Apache 2.0',
+ 'keywords': 'mesos',
+ 'classifiers': [ ]
+}
+
+from setuptools import setup
+
+setup(**config)
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/python/interface/src/mesos/__init__.py
----------------------------------------------------------------------
diff --git a/src/python/interface/src/mesos/__init__.py
b/src/python/interface/src/mesos/__init__.py
new file mode 100644
index 0000000..f48ad10
--- /dev/null
+++ b/src/python/interface/src/mesos/__init__.py
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/python/interface/src/mesos/interface/__init__.py
----------------------------------------------------------------------
diff --git a/src/python/interface/src/mesos/interface/__init__.py
b/src/python/interface/src/mesos/interface/__init__.py
new file mode 100644
index 0000000..818f41b
--- /dev/null
+++ b/src/python/interface/src/mesos/interface/__init__.py
@@ -0,0 +1,347 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# See include/mesos/scheduler.hpp, include/mesos/executor.hpp and
+# include/mesos/mesos.proto for more information documenting this
+# interface.
+
+"""Python bindings for Mesos."""
+
+from __future__ import print_function
+
+import sys
+
+__all__ = (
+ 'Executor',
+ 'ExecutorDriver'
+ 'Scheduler',
+ 'SchedulerDriver',
+)
+
+class Scheduler(object):
+ """
+ Base class for Mesos schedulers. Users' schedulers should extend this
+ class to get default implementations of methods they don't override.
+ """
+
+ def registered(self, driver, frameworkId, masterInfo):
+ """
+ Invoked when the scheduler successfully registers with a Mesos master.
+ It is called with the frameworkId, a unique ID generated by the
+ master, and the masterInfo which is information about the master
+ itself.
+ """
+
+ def reregistered(self, driver, masterInfo):
+ """
+ Invoked when the scheduler re-registers with a newly elected Mesos
+ master. This is only called when the scheduler has previously been
+ registered. masterInfo contains information about the newly elected
+ master.
+ """
+
+ def disconnected(self, driver):
+ """
+ Invoked when the scheduler becomes disconnected from the master, e.g.
+ the master fails and another is taking over.
+ """
+
+ def resourceOffers(self, driver, offers):
+ """
+ Invoked when resources have been offered to this framework. A single
+ offer will only contain resources from a single slave. Resources
+ associated with an offer will not be re-offered to _this_ framework
+ until either (a) this framework has rejected those resources (see
+ SchedulerDriver.launchTasks) or (b) those resources have been
+ rescinded (see Scheduler.offerRescinded). Note that resources may be
+ concurrently offered to more than one framework at a time (depending
+ on the allocator being used). In that case, the first framework to
+ launch tasks using those resources will be able to use them while the
+ other frameworks will have those resources rescinded (or if a
+ framework has already launched tasks with those resources then those
+ tasks will fail with a TASK_LOST status and a message saying as much).
+ """
+
+ def offerRescinded(self, driver, offerId):
+ """
+ Invoked when an offer is no longer valid (e.g., the slave was lost or
+ another framework used resources in the offer.) If for whatever reason
+ an offer is never rescinded (e.g., dropped message, failing over
+ framework, etc.), a framwork that attempts to launch tasks using an
+ invalid offer will receive TASK_LOST status updats for those tasks
+ (see Scheduler.resourceOffers).
+ """
+
+ def statusUpdate(self, driver, status):
+ """
+ Invoked when the status of a task has changed (e.g., a slave is lost
+ and so the task is lost, a task finishes and an executor sends a
+ status update saying so, etc.) Note that returning from this callback
+ acknowledges receipt of this status update. If for whatever reason
+ the scheduler aborts during this callback (or the process exits)
+ another status update will be delivered. Note, however, that this is
+ currently not true if the slave sending the status update is lost or
+ fails during that time.
+ """
+
+ def frameworkMessage(self, driver, executorId, slaveId, message):
+ """
+ Invoked when an executor sends a message. These messages are best
+ effort; do not expect a framework message to be retransmitted in any
+ reliable fashion.
+ """
+
+ def slaveLost(self, driver, slaveId):
+ """
+ Invoked when a slave has been determined unreachable (e.g., machine
+ failure, network partition.) Most frameworks will need to reschedule
+ any tasks launched on this slave on a new slave.
+ """
+
+ def executorLost(self, driver, executorId, slaveId, status):
+ """
+ Invoked when an executor has exited/terminated. Note that any tasks
+ running will have TASK_LOST status updates automatically generated.
+ """
+
+ def error(self, driver, message):
+ """
+ Invoked when there is an unrecoverable error in the scheduler or
+ scheduler driver. The driver will be aborted BEFORE invoking this
+ callback.
+ """
+ print("Error from Mesos: %s " % message, file=sys.stderr)
+
+
+class SchedulerDriver(object):
+ """
+ Interface for Mesos scheduler drivers. Users may wish to implement this
+ class in mock objects for tests.
+ """
+ def start(self):
+ """
+ Starts the scheduler driver. This needs to be called before any other
+ driver calls are made.
+ """
+
+ def stop(self, failover=False):
+ """
+ Stops the scheduler driver. If the 'failover' flag is set to False
+ then it is expected that this framework will never reconnect to Mesos
+ and all of its executors and tasks can be terminated. Otherwise, all
+ executors and tasks will remain running (for some framework specific
+ failover timeout) allowing the scheduler to reconnect (possibly in the
+ same process, or from a different process, for example, on a different
+ machine.)
+ """
+
+ def abort(self):
+ """
+ Aborts the driver so that no more callbacks can be made to the
+ scheduler. The semantics of abort and stop have deliberately been
+ separated so that code can detect an aborted driver (i.e., via the
+ return status of SchedulerDriver.join), and instantiate and start
+ another driver if desired (from within the same process.)
+ """
+
+ def join(self):
+ """
+ Waits for the driver to be stopped or aborted, possibly blocking the
+ current thread indefinitely. The return status of this function can
+ be used to determine if the driver was aborted (see mesos.proto for a
+ description of Status).
+ """
+
+ def run(self):
+ """
+ Starts and immediately joins (i.e., blocks on) the driver.
+ """
+
+ def requestResources(self, requests):
+ """
+ Requests resources from Mesos (see mesos.proto for a description of
+ Request and how, for example, to request resources from specific
+ slaves.) Any resources available are offered to the framework via
+ Scheduler.resourceOffers callback, asynchronously.
+ """
+
+ def launchTasks(self, offerIds, tasks, filters=None):
+ """
+ Launches the given set of tasks. Any resources remaining (i.e., not
+ used by the tasks or their executors) will be considered declined.
+ The specified filters are applied on all unused resources (see
+ mesos.proto for a description of Filters.) Invoking this function with
+ an empty collection of tasks declines the offers in entirety (see
+ Scheduler.declineOffer). Note that passing a single offer is also
+ supported.
+ """
+
+ def killTask(self, taskId):
+ """
+ Kills the specified task. Note that attempting to kill a task is
+ currently not reliable. If, for example, a scheduler fails over while
+ it was attempting to kill a task it will need to retry in the future.
+ Likewise, if unregistered / disconnected, the request will be dropped
+ dropped (these semantics may be changed in the future).
+ """
+
+ def declineOffer(self, offerId, filters=None):
+ """
+ Declines an offer in its entirety and applies the specified
+ filters on the resources (see mesos.proto for a description of
+ Filters). Note that this can be done at any time, it is not
+ necessary to do this within the Scheduler::resourceOffers
+ callback.
+ """
+
+ def reviveOffers(self):
+ """
+ Removes all filters previously set by the framework (via
+ launchTasks()). This enables the framework to receive offers from
+ those filtered slaves.
+ """
+
+ def sendFrameworkMessage(self, executorId, slaveId, data):
+ """
+ Sends a message from the framework to one of its executors. These
+ messages are best effort; do not expect a framework message to be
+ retransmitted in any reliable fashion.
+ """
+
+ # TODO(bmahler): Add reconcileTasks!
+
+class Executor(object):
+ """
+ Base class for Mesos executors. Users' executors should extend this
+ class to get default implementations of methods they don't override.
+ """
+
+ def registered(self, driver, executorInfo, frameworkInfo, slaveInfo):
+ """
+ Invoked once the executor driver has been able to successfully connect
+ with Mesos. In particular, a scheduler can pass some data to its
+ executors through the FrameworkInfo.ExecutorInfo's data field.
+ """
+
+ def reregistered(self, driver, slaveInfo):
+ """
+ Invoked when the executor re-registers with a restarted slave.
+ """
+
+ def disconnected(self, driver):
+ """
+ Invoked when the executor becomes "disconnected" from the slave (e.g.,
+ the slave is being restarted due to an upgrade).
+ """
+
+ def launchTask(self, driver, task):
+ """
+ Invoked when a task has been launched on this executor (initiated via
+ Scheduler.launchTasks). Note that this task can be realized with a
+ thread, a process, or some simple computation, however, no other
+ callbacks will be invoked on this executor until this callback has
+ returned.
+ """
+
+ def killTask(self, driver, taskId):
+ """
+ Invoked when a task running within this executor has been killed (via
+ SchedulerDriver.killTask). Note that no status update will be sent on
+ behalf of the executor, the executor is responsible for creating a new
+ TaskStatus (i.e., with TASK_KILLED) and invoking ExecutorDriver's
+ sendStatusUpdate.
+ """
+
+ def frameworkMessage(self, driver, message):
+ """
+ Invoked when a framework message has arrived for this executor. These
+ messages are best effort; do not expect a framework message to be
+ retransmitted in any reliable fashion.
+ """
+
+ def shutdown(self, driver):
+ """
+ Invoked when the executor should terminate all of its currently
+ running tasks. Note that after Mesos has determined that an executor
+ has terminated any tasks that the executor did not send terminal
+ status updates for (e.g., TASK_KILLED, TASK_FINISHED, TASK_FAILED,
+ etc) a TASK_LOST status update will be created.
+ """
+
+ def error(self, driver, message):
+ """
+ Invoked when a fatal error has occured with the executor and/or
+ executor driver. The driver will be aborted BEFORE invoking this
+ callback.
+ """
+ print("Error from Mesos: %s" % message, file=sys.stderr)
+
+
+
+class ExecutorDriver(object):
+ """
+ Interface for Mesos executor drivers. Users may wish to extend this
+ class in mock objects for tests.
+ """
+ def start(self):
+ """
+ Starts the executor driver. This needs to be called before any other
+ driver calls are made.
+ """
+
+ def stop(self):
+ """
+ Stops the executor driver.
+ """
+
+ def abort(self):
+ """
+ Aborts the driver so that no more callbacks can be made to the
+ executor. The semantics of abort and stop have deliberately been
+ separated so that code can detect an aborted driver (i.e., via the
+ return status of ExecutorDriver.join), and instantiate and start
+ another driver if desired (from within the same process, although this
+ functionality is currently not supported for executors).
+ """
+
+ def join(self):
+ """
+ Waits for the driver to be stopped or aborted, possibly blocking the
+ current thread indefinitely. The return status of this function can
+ be used to determine if the driver was aborted (see mesos.proto for a
+ description of Status).
+ """
+
+ def run(self):
+ """
+ Starts and immediately joins (i.e., blocks on) the driver.
+ """
+
+ def sendStatusUpdate(self, status):
+ """
+ Sends a status update to the framework scheduler, retrying as
+ necessary until an acknowledgement has been received or the executor
+ is terminated (in which case, a TASK_LOST status update will be sent).
+ See Scheduler.statusUpdate for more information about status update
+ acknowledgements.
+ """
+
+ def sendFrameworkMessage(self, data):
+ """
+ Sends a message to the framework scheduler. These messages are best
+ effort; do not expect a framework message to be retransmitted in any
+ reliable fashion.
+ """
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/python/native/ext_modules.py.in
----------------------------------------------------------------------
diff --git a/src/python/native/ext_modules.py.in
b/src/python/native/ext_modules.py.in
new file mode 100644
index 0000000..a0f74b2
--- /dev/null
+++ b/src/python/native/ext_modules.py.in
@@ -0,0 +1,131 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import errno
+import glob
+import os
+import shutil
+
+from setuptools import Extension
+
+abs_top_srcdir = '@abs_top_srcdir@'
+abs_top_builddir = '@abs_top_builddir@'
+
+src_python_native = os.path.join(
+ 'src', 'python', 'native', 'src', 'mesos', 'native')
+
+leveldb = os.path.join('3rdparty', 'leveldb')
+zookeeper = os.path.join('3rdparty', 'zookeeper-3.4.5', 'src', 'c')
+libprocess = os.path.join('3rdparty', 'libprocess')
+
+# Even though a statically compiled libprocess should include glog,
+# libev, gperftools, and protobuf before installation this isn't the
+# case, so while a libtool managed build will correctly pull in these
+# libraries when building the final result, we need to explicitly
+# include them here (or more precisely, down where we actually include
+# libev.a and libprofiler.a).
+glog = os.path.join(libprocess, '3rdparty', 'glog-0.3.3')
+libev = os.path.join(libprocess, '3rdparty', 'libev-4.15')
+gperftools = os.path.join(libprocess, '3rdparty', 'gperftools-2.0')
+protobuf = os.path.join(libprocess, '3rdparty', 'protobuf-2.5.0')
+
+# Build the list of source files. Note that each source must be
+# relative to our current directory (where this script lives).
+SOURCES = [
+ os.path.join('src', 'mesos', 'native', file)
+ for file in os.listdir(os.path.join(abs_top_srcdir, src_python_native))
+ if file.endswith('.cpp')
+]
+
+INCLUDE_DIRS = [
+ os.path.join(abs_top_srcdir, 'include'),
+ os.path.join(abs_top_builddir, 'include'),
+ # Needed for the *.pb.h protobuf includes.
+ os.path.join(abs_top_builddir, 'include', 'mesos'),
+ os.path.join(abs_top_builddir, 'src'),
+ os.path.join(abs_top_builddir, src_python_native),
+ os.path.join(abs_top_builddir, protobuf, 'src'),
+]
+
+LIBRARY_DIRS = []
+
+EXTRA_OBJECTS = [
+ os.path.join(abs_top_builddir, 'src', '.libs', 'libmesos_no_3rdparty.a'),
+ os.path.join(abs_top_builddir, protobuf, 'src', '.libs', 'libprotobuf.a'),
+ os.path.join(abs_top_builddir, libprocess, '.libs', 'libprocess.a'),
+ os.path.join(abs_top_builddir, glog, '.libs', 'libglog.a')
+]
+
+# For leveldb, we need to check for the presence of libleveldb.a, since
+# it is possible to disable leveldb inside mesos.
+libev = os.path.join(abs_top_builddir, libev, '.libs', 'libev.a')
+libleveldb = os.path.join(abs_top_builddir, leveldb, 'libleveldb.a')
+libzookeeper = os.path.join(
+ abs_top_builddir, zookeeper, '.libs', 'libzookeeper_mt.a')
+
+if os.path.exists(libleveldb):
+ EXTRA_OBJECTS.append(libleveldb)
+else:
+ EXTRA_OBJECTS.append('-lleveldb')
+
+if os.path.exists(libzookeeper):
+ EXTRA_OBJECTS.append(libzookeeper)
+else:
+ EXTRA_OBJECTS.append('-lzookeeper_mt')
+
+if os.path.exists(libev):
+ EXTRA_OBJECTS.append(libev)
+else:
+ EXTRA_OBJECTS.append('-lev')
+
+# For gperftools, we need to check for the presence of libprofiler.a, since
+# it is possible to disable perftools inside libprocess.
+libprofiler = os.path.join(
+ abs_top_builddir, gperftools, '.libs', 'libprofiler.a')
+
+if os.path.exists(libprofiler):
+ EXTRA_OBJECTS.append(libprofiler)
+
+EXTRA_LINK_ARGS = []
+
+# Add any flags from LDFLAGS.
+if 'LDFLAGS' in os.environ:
+ for flag in os.environ['LDFLAGS'].split():
+ EXTRA_LINK_ARGS.append(flag)
+
+# Add any libraries from LIBS.
+if 'LIBS' in os.environ:
+ for library in os.environ['LIBS'].split():
+ EXTRA_LINK_ARGS.append(library)
+
+DEPENDS = [
+ os.path.join(abs_top_srcdir, 'src', 'python', source)
+ for source in SOURCES
+]
+
+# Note that we add EXTRA_OBJECTS to our dependency list to make sure
+# that we rebuild this module when one of them changes (e.g.,
+# libprocess).
+mesos_module = \
+ Extension('mesos.native._mesos',
+ sources = SOURCES,
+ include_dirs = INCLUDE_DIRS,
+ library_dirs = LIBRARY_DIRS,
+ extra_objects = EXTRA_OBJECTS,
+ extra_link_args = EXTRA_LINK_ARGS,
+ depends = EXTRA_OBJECTS,
+ language = 'c++',
+ )
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/python/native/mesos_executor_driver_impl.cpp
----------------------------------------------------------------------
diff --git a/src/python/native/mesos_executor_driver_impl.cpp
b/src/python/native/mesos_executor_driver_impl.cpp
deleted file mode 100644
index 16b9bc1..0000000
--- a/src/python/native/mesos_executor_driver_impl.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Python.h must be included before standard headers.
-// See: http://docs.python.org/2/c-api/intro.html#include-files
-#include <Python.h>
-
-#include <string>
-
-#include "mesos_executor_driver_impl.hpp"
-#include "module.hpp"
-#include "proxy_executor.hpp"
-
-using namespace mesos;
-using namespace mesos::python;
-
-using std::cerr;
-using std::endl;
-using std::string;
-using std::vector;
-using std::map;
-
-
-namespace mesos { namespace python {
-
-/**
- * Python type object for MesosExecutorDriverImpl.
- */
-PyTypeObject MesosExecutorDriverImplType = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "_mesos.MesosExecutorDriverImpl", /* tp_name */
- sizeof(MesosExecutorDriverImpl), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) MesosExecutorDriverImpl_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- "Private MesosExecutorDriver implementation", /* tp_doc */
- (traverseproc) MesosExecutorDriverImpl_traverse, /* tp_traverse */
- (inquiry) MesosExecutorDriverImpl_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- MesosExecutorDriverImpl_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc) MesosExecutorDriverImpl_init, /* tp_init */
- 0, /* tp_alloc */
- MesosExecutorDriverImpl_new, /* tp_new */
-};
-
-
-/**
- * List of Python methods in MesosExecutorDriverImpl.
- */
-PyMethodDef MesosExecutorDriverImpl_methods[] = {
- { "start",
- (PyCFunction) MesosExecutorDriverImpl_start,
- METH_NOARGS,
- "Start the driver to connect to Mesos"
- },
- { "stop",
- (PyCFunction) MesosExecutorDriverImpl_stop,
- METH_NOARGS,
- "Stop the driver, disconnecting from Mesos"
- },
- { "abort",
- (PyCFunction) MesosExecutorDriverImpl_abort,
- METH_NOARGS,
- "Abort the driver, disallowing calls from and to the driver"
- },
- { "join",
- (PyCFunction) MesosExecutorDriverImpl_join,
- METH_NOARGS,
- "Wait for a running driver to disconnect from Mesos"
- },
- { "run",
- (PyCFunction) MesosExecutorDriverImpl_run,
- METH_NOARGS,
- "Start a driver and run it, returning when it disconnects from Mesos"
- },
- { "sendStatusUpdate",
- (PyCFunction) MesosExecutorDriverImpl_sendStatusUpdate,
- METH_VARARGS,
- "Send a status update for a task"
- },
- { "sendFrameworkMessage",
- (PyCFunction) MesosExecutorDriverImpl_sendFrameworkMessage,
- METH_VARARGS,
- "Send a FrameworkMessage to a slave"
- },
- { NULL } /* Sentinel */
-};
-
-
-/**
- * Create, but don't initialize, a new MesosExecutorDriverImpl
- * (called by Python before init method).
- */
-PyObject* MesosExecutorDriverImpl_new(PyTypeObject *type,
- PyObject *args,
- PyObject *kwds)
-{
- MesosExecutorDriverImpl *self;
- self = (MesosExecutorDriverImpl *) type->tp_alloc(type, 0);
- if (self != NULL) {
- self->driver = NULL;
- self->proxyExecutor = NULL;
- self->pythonExecutor = NULL;
- }
- return (PyObject*) self;
-}
-
-
-/**
- * Initialize a MesosExecutorDriverImpl with constructor arguments.
- */
-int MesosExecutorDriverImpl_init(MesosExecutorDriverImpl *self,
- PyObject *args,
- PyObject *kwds)
-{
- PyObject *pythonExecutor = NULL;
-
- if (!PyArg_ParseTuple(args, "O", &pythonExecutor)) {
- return -1;
- }
-
- if (pythonExecutor != NULL) {
- PyObject* tmp = self->pythonExecutor;
- Py_INCREF(pythonExecutor);
- self->pythonExecutor = pythonExecutor;
- Py_XDECREF(tmp);
- }
-
- if (self->driver != NULL) {
- delete self->driver;
- self->driver = NULL;
- }
-
- if (self->proxyExecutor != NULL) {
- delete self->proxyExecutor;
- self->proxyExecutor = NULL;
- }
-
- self->proxyExecutor = new ProxyExecutor(self);
- self->driver = new MesosExecutorDriver(self->proxyExecutor);
-
- return 0;
-}
-
-
-/**
- * Free a MesosExecutorDriverImpl.
- */
-void MesosExecutorDriverImpl_dealloc(MesosExecutorDriverImpl* self)
-{
- if (self->driver != NULL) {
- // We need to wrap the driver destructor in an "allow threads"
- // macro since the MesosExecutorDriver destructor waits for the
- // ExecutorProcess to terminate and there might be a thread that
- // is trying to acquire the GIL to call through the
- // ProxyExecutor. It will only be after this thread executes that
- // the ExecutorProcess might actually get a terminate.
- Py_BEGIN_ALLOW_THREADS
- delete self->driver;
- Py_END_ALLOW_THREADS
- self->driver = NULL;
- }
-
- if (self->proxyExecutor != NULL) {
- delete self->proxyExecutor;
- self->proxyExecutor = NULL;
- }
-
- MesosExecutorDriverImpl_clear(self);
- self->ob_type->tp_free((PyObject*) self);
-}
-
-
-/**
- * Traverse fields of a MesosExecutorDriverImpl on a cyclic GC search.
- * See http://docs.python.org/extending/newtypes.html.
- */
-int MesosExecutorDriverImpl_traverse(MesosExecutorDriverImpl* self,
- visitproc visit,
- void* arg)
-{
- Py_VISIT(self->pythonExecutor);
- return 0;
-}
-
-
-/**
- * Clear fields of a MesosExecutorDriverImpl that can participate in
- * GC cycles. See http://docs.python.org/extending/newtypes.html.
- */
-int MesosExecutorDriverImpl_clear(MesosExecutorDriverImpl* self)
-{
- Py_CLEAR(self->pythonExecutor);
- return 0;
-}
-
-
-PyObject* MesosExecutorDriverImpl_start(MesosExecutorDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status = self->driver->start();
- return PyInt_FromLong(status); // Sets an exception if creating the int fails
-}
-
-
-PyObject* MesosExecutorDriverImpl_stop(MesosExecutorDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status = self->driver->stop();
- return PyInt_FromLong(status); // Sets an exception if creating the int fails
-}
-
-
-PyObject* MesosExecutorDriverImpl_abort(MesosExecutorDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status = self->driver->abort();
- return PyInt_FromLong(status); // Sets an exception if creating the int fails
-}
-
-
-PyObject* MesosExecutorDriverImpl_join(MesosExecutorDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status;
- Py_BEGIN_ALLOW_THREADS
- status = self->driver->join();
- Py_END_ALLOW_THREADS
- return PyInt_FromLong(status); // Sets an exception if creating the int fails
-}
-
-
-PyObject* MesosExecutorDriverImpl_run(MesosExecutorDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status;
- Py_BEGIN_ALLOW_THREADS
- status = self->driver->run();
- Py_END_ALLOW_THREADS
- return PyInt_FromLong(status); // Sets an exception if creating the int fails
-}
-
-
-PyObject* MesosExecutorDriverImpl_sendStatusUpdate(
- MesosExecutorDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is NULL");
- return NULL;
- }
-
- PyObject* statusObj = NULL;
- TaskStatus taskStatus;
- if (!PyArg_ParseTuple(args, "O", &statusObj)) {
- return NULL;
- }
- if (!readPythonProtobuf(statusObj, &taskStatus)) {
- PyErr_Format(PyExc_Exception,
- "Could not deserialize Python TaskStatus");
- return NULL;
- }
-
- Status status = self->driver->sendStatusUpdate(taskStatus);
- return PyInt_FromLong(status); // Sets an exception if creating the int fails
-}
-
-
-PyObject* MesosExecutorDriverImpl_sendFrameworkMessage(
- MesosExecutorDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is NULL");
- return NULL;
- }
-
- const char* data;
- int length;
- if (!PyArg_ParseTuple(args, "s#", &data, &length)) {
- return NULL;
- }
-
- Status status = self->driver->sendFrameworkMessage(string(data, length));
- return PyInt_FromLong(status); // Sets an exception if creating the int fails
-}
-
-} // namespace python {
-} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/python/native/mesos_executor_driver_impl.hpp
----------------------------------------------------------------------
diff --git a/src/python/native/mesos_executor_driver_impl.hpp
b/src/python/native/mesos_executor_driver_impl.hpp
deleted file mode 100644
index 7245414..0000000
--- a/src/python/native/mesos_executor_driver_impl.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MESOS_EXECUTOR_DRIVER_IMPL_HPP
-#define MESOS_EXECUTOR_DRIVER_IMPL_HPP
-
-#include <mesos/executor.hpp>
-
-
-namespace mesos { namespace python {
-
-class ProxyExecutor;
-
-/**
- * Python object structure for MesosExecutorDriverImpl objects.
- */
-struct MesosExecutorDriverImpl {
- PyObject_HEAD
- /* Type-specific fields go here. */
- MesosExecutorDriver* driver;
- ProxyExecutor* proxyExecutor;
- PyObject* pythonExecutor;
-};
-
-/**
- * Python type object for MesosExecutorDriverImpl.
- */
-extern PyTypeObject MesosExecutorDriverImplType;
-
-/**
- * List of Python methods in MesosExecutorDriverImpl.
- */
-extern PyMethodDef MesosExecutorDriverImpl_methods[];
-
-/**
- * Create, but don't initialize, a new MesosExecutorDriverImpl
- * (called by Python before init method).
- */
-PyObject* MesosExecutorDriverImpl_new(PyTypeObject *type,
- PyObject *args,
- PyObject *kwds);
-
-/**
- * Initialize a MesosExecutorDriverImpl with constructor arguments.
- */
-int MesosExecutorDriverImpl_init(MesosExecutorDriverImpl *self,
- PyObject *args,
- PyObject *kwds);
-
-/**
- * Free a MesosExecutorDriverImpl.
- */
-void MesosExecutorDriverImpl_dealloc(MesosExecutorDriverImpl* self);
-
-/**
- * Traverse fields of a MesosExecutorDriverImpl on a cyclic GC search.
- * See http://docs.python.org/extending/newtypes.html.
- */
-int MesosExecutorDriverImpl_traverse(MesosExecutorDriverImpl* self,
- visitproc visit,
- void* arg);
-/**
- * Clear fields of a MesosExecutorDriverImpl that can participate in
- * GC cycles. See http://docs.python.org/extending/newtypes.html.
- */
-int MesosExecutorDriverImpl_clear(MesosExecutorDriverImpl* self);
-
-// MesosExecutorDriverImpl methods
-PyObject* MesosExecutorDriverImpl_start(MesosExecutorDriverImpl* self);
-
-PyObject* MesosExecutorDriverImpl_stop(MesosExecutorDriverImpl* self);
-
-PyObject* MesosExecutorDriverImpl_abort(MesosExecutorDriverImpl* self);
-
-PyObject* MesosExecutorDriverImpl_join(MesosExecutorDriverImpl* self);
-
-PyObject* MesosExecutorDriverImpl_run(MesosExecutorDriverImpl* self);
-
-PyObject* MesosExecutorDriverImpl_sendStatusUpdate(
- MesosExecutorDriverImpl* self,
- PyObject* args);
-
-PyObject* MesosExecutorDriverImpl_sendFrameworkMessage(
- MesosExecutorDriverImpl* self,
- PyObject* args);
-
-} // namespace python {
-} // namespace mesos {
-
-#endif /* MESOS_EXECUTOR_DRIVER_IMPL_HPP */
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/python/native/mesos_scheduler_driver_impl.cpp
----------------------------------------------------------------------
diff --git a/src/python/native/mesos_scheduler_driver_impl.cpp
b/src/python/native/mesos_scheduler_driver_impl.cpp
deleted file mode 100644
index e014eed..0000000
--- a/src/python/native/mesos_scheduler_driver_impl.cpp
+++ /dev/null
@@ -1,634 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Python.h must be included before standard headers.
-// See: http://docs.python.org/2/c-api/intro.html#include-files
-#include <Python.h>
-
-#include <string>
-
-#include "mesos_scheduler_driver_impl.hpp"
-#include "module.hpp"
-#include "proxy_scheduler.hpp"
-
-using namespace mesos;
-using namespace mesos::python;
-
-using std::cerr;
-using std::endl;
-using std::string;
-using std::vector;
-using std::map;
-
-namespace mesos {
-namespace python {
-
-/**
- * Python type object for MesosSchedulerDriverImpl.
- */
-PyTypeObject MesosSchedulerDriverImplType = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "_mesos.MesosSchedulerDriverImpl", /* tp_name */
- sizeof(MesosSchedulerDriverImpl), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) MesosSchedulerDriverImpl_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- "Private MesosSchedulerDriver implementation", /* tp_doc */
- (traverseproc) MesosSchedulerDriverImpl_traverse, /* tp_traverse */
- (inquiry) MesosSchedulerDriverImpl_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- MesosSchedulerDriverImpl_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc) MesosSchedulerDriverImpl_init, /* tp_init */
- 0, /* tp_alloc */
- MesosSchedulerDriverImpl_new, /* tp_new */
-};
-
-
-/**
- * List of Python methods in MesosSchedulerDriverImpl.
- */
-PyMethodDef MesosSchedulerDriverImpl_methods[] = {
- { "start",
- (PyCFunction) MesosSchedulerDriverImpl_start,
- METH_NOARGS,
- "Start the driver to connect to Mesos"
- },
- { "stop",
- (PyCFunction) MesosSchedulerDriverImpl_stop,
- METH_VARARGS,
- "Stop the driver, disconnecting from Mesos"
- },
- { "abort",
- (PyCFunction) MesosSchedulerDriverImpl_abort,
- METH_NOARGS,
- "Abort the driver, disabling calls from and to the driver"
- },
- { "join",
- (PyCFunction) MesosSchedulerDriverImpl_join,
- METH_NOARGS,
- "Wait for a running driver to disconnect from Mesos"
- },
- { "run",
- (PyCFunction) MesosSchedulerDriverImpl_run,
- METH_NOARGS,
- "Start a driver and run it, returning when it disconnects from Mesos"
- },
- { "requestResources",
- (PyCFunction) MesosSchedulerDriverImpl_requestResources,
- METH_VARARGS,
- "Request resources from the Mesos allocator"
- },
- { "launchTasks",
- (PyCFunction) MesosSchedulerDriverImpl_launchTasks,
- METH_VARARGS,
- "Reply to a Mesos offer with a list of tasks"
- },
- { "killTask",
- (PyCFunction) MesosSchedulerDriverImpl_killTask,
- METH_VARARGS,
- "Kill the task with the given ID"
- },
- { "declineOffer",
- (PyCFunction) MesosSchedulerDriverImpl_declineOffer,
- METH_VARARGS,
- "Decline a Mesos offer"
- },
- { "reviveOffers",
- (PyCFunction) MesosSchedulerDriverImpl_reviveOffers,
- METH_NOARGS,
- "Remove all filters and ask Mesos for new offers"
- },
- { "sendFrameworkMessage",
- (PyCFunction) MesosSchedulerDriverImpl_sendFrameworkMessage,
- METH_VARARGS,
- "Send a FrameworkMessage to a slave"
- },
- { "reconcileTasks",
- (PyCFunction) MesosSchedulerDriverImpl_reconcileTasks,
- METH_VARARGS,
- "Master sends status updates if task status is different from expected"
- },
- { NULL } /* Sentinel */
-};
-
-
-/**
- * Create, but don't initialize, a new MesosSchedulerDriverImpl
- * (called by Python before init method).
- */
-PyObject* MesosSchedulerDriverImpl_new(PyTypeObject* type,
- PyObject* args,
- PyObject* kwds)
-{
- MesosSchedulerDriverImpl* self;
- self = (MesosSchedulerDriverImpl*) type->tp_alloc(type, 0);
- if (self != NULL) {
- self->driver = NULL;
- self->proxyScheduler = NULL;
- self->pythonScheduler = NULL;
- }
- return (PyObject*) self;
-}
-
-
-/**
- * Initialize a MesosSchedulerDriverImpl with constructor arguments.
- */
-int MesosSchedulerDriverImpl_init(MesosSchedulerDriverImpl* self,
- PyObject* args,
- PyObject* kwds)
-{
- PyObject* schedulerObj = NULL;
- PyObject* frameworkObj = NULL;
- const char* master;
- PyObject* credentialObj = NULL;
-
- if (!PyArg_ParseTuple(
- args, "OOs|O", &schedulerObj, &frameworkObj, &master, &credentialObj)) {
- return -1;
- }
-
- if (schedulerObj != NULL) {
- PyObject* tmp = self->pythonScheduler;
- Py_INCREF(schedulerObj);
- self->pythonScheduler = schedulerObj;
- Py_XDECREF(tmp);
- }
-
- FrameworkInfo framework;
- if (frameworkObj != NULL) {
- if (!readPythonProtobuf(frameworkObj, &framework)) {
- PyErr_Format(PyExc_Exception,
- "Could not deserialize Python FrameworkInfo");
- return -1;
- }
- }
-
- Credential credential;
- if (credentialObj != NULL) {
- if (!readPythonProtobuf(credentialObj, &credential)) {
- PyErr_Format(PyExc_Exception, "Could not deserialize Python Credential");
- return -1;
- }
- }
-
-
- if (self->driver != NULL) {
- delete self->driver;
- self->driver = NULL;
- }
-
- if (self->proxyScheduler != NULL) {
- delete self->proxyScheduler;
- self->proxyScheduler = NULL;
- }
-
- self->proxyScheduler = new ProxyScheduler(self);
-
- if (credentialObj != NULL) {
- self->driver = new MesosSchedulerDriver(
- self->proxyScheduler, framework, master, credential);
- } else {
- self->driver = new MesosSchedulerDriver(
- self->proxyScheduler, framework, master);
- }
-
- return 0;
-}
-
-
-/**
- * Free a MesosSchedulerDriverImpl.
- */
-void MesosSchedulerDriverImpl_dealloc(MesosSchedulerDriverImpl* self)
-{
- if (self->driver != NULL) {
- // We need to wrap the driver destructor in an "allow threads"
- // macro since the MesosSchedulerDriver destructor waits for the
- // SchedulerProcess to terminate and there might be a thread that
- // is trying to acquire the GIL to call through the
- // ProxyScheduler. It will only be after this thread executes that
- // the SchedulerProcess might actually get a terminate.
- Py_BEGIN_ALLOW_THREADS
- delete self->driver;
- Py_END_ALLOW_THREADS
- self->driver = NULL;
- }
-
- if (self->proxyScheduler != NULL) {
- delete self->proxyScheduler;
- self->proxyScheduler = NULL;
- }
-
- MesosSchedulerDriverImpl_clear(self);
- self->ob_type->tp_free((PyObject*) self);
-}
-
-
-/**
- * Traverse fields of a MesosSchedulerDriverImpl on a cyclic GC search.
- * See http://docs.python.org/extending/newtypes.html.
- */
-int MesosSchedulerDriverImpl_traverse(MesosSchedulerDriverImpl* self,
- visitproc visit,
- void* arg)
-{
- Py_VISIT(self->pythonScheduler);
- return 0;
-}
-
-
-/**
- * Clear fields of a MesosSchedulerDriverImpl that can participate in
- * GC cycles. See http://docs.python.org/extending/newtypes.html.
- */
-int MesosSchedulerDriverImpl_clear(MesosSchedulerDriverImpl* self)
-{
- Py_CLEAR(self->pythonScheduler);
- return 0;
-}
-
-
-PyObject* MesosSchedulerDriverImpl_start(MesosSchedulerDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status = self->driver->start();
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_stop(MesosSchedulerDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- bool failover = false; // Should match default in mesos.py.
-
- if (!PyArg_ParseTuple(args, "|b", &failover)) {
- return NULL;
- }
-
- Status status = self->driver->stop(failover);
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_abort(MesosSchedulerDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status = self->driver->abort();
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_join(MesosSchedulerDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status;
- Py_BEGIN_ALLOW_THREADS
- status = self->driver->join();
- Py_END_ALLOW_THREADS
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_run(MesosSchedulerDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status;
- Py_BEGIN_ALLOW_THREADS
- status = self->driver->run();
- Py_END_ALLOW_THREADS
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_requestResources(
- MesosSchedulerDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- PyObject* requestsObj = NULL;
- vector<Request> requests;
-
- if (!PyArg_ParseTuple(args, "O", &requestsObj)) {
- return NULL;
- }
-
- if (!PyList_Check(requestsObj)) {
- PyErr_Format(PyExc_Exception,
- "Parameter 2 to requestsResources is not a list");
- return NULL;
- }
- Py_ssize_t len = PyList_Size(requestsObj);
- for (int i = 0; i < len; i++) {
- PyObject* requestObj = PyList_GetItem(requestsObj, i);
- if (requestObj == NULL) {
- return NULL; // Exception will have been set by PyList_GetItem
- }
- Request request;
- if (!readPythonProtobuf(requestObj, &request)) {
- PyErr_Format(PyExc_Exception, "Could not deserialize Python Request");
- return NULL;
- }
- requests.push_back(request);
- }
-
- Status status = self->driver->requestResources(requests);
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_launchTasks(MesosSchedulerDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- PyObject* offerIdsObj = NULL;
- PyObject* tasksObj = NULL;
- PyObject* filtersObj = NULL;
- vector<OfferID> offerIds;
- vector<TaskInfo> tasks;
- Filters filters;
-
- if (!PyArg_ParseTuple(args, "OO|O", &offerIdsObj, &tasksObj, &filtersObj)) {
- return NULL;
- }
-
- // Offer argument can be a list of offer ids or a single offer id (for
- // backward compatibility).
- if (!PyList_Check(offerIdsObj)) {
- OfferID offerId;
- if (!readPythonProtobuf(offerIdsObj, &offerId)) {
- PyErr_Format(PyExc_Exception, "Could not deserialize Python OfferID");
- return NULL;
- }
- offerIds.push_back(offerId);
- } else {
- Py_ssize_t len = PyList_Size(offerIdsObj);
- for (int i = 0; i < len; i++) {
- PyObject* offerObj = PyList_GetItem(offerIdsObj, i);
- if (offerObj == NULL) {
- return NULL;
- }
- OfferID offerId;
- if (!readPythonProtobuf(offerObj, &offerId)) {
- PyErr_Format(PyExc_Exception,
- "Could not deserialize Python OfferID");
- return NULL;
- }
- offerIds.push_back(offerId);
- }
- }
-
- if (!PyList_Check(tasksObj)) {
- PyErr_Format(PyExc_Exception, "Parameter 2 to launchTasks is not a list");
- return NULL;
- }
- Py_ssize_t len = PyList_Size(tasksObj);
- for (int i = 0; i < len; i++) {
- PyObject* taskObj = PyList_GetItem(tasksObj, i);
- if (taskObj == NULL) {
- return NULL; // Exception will have been set by PyList_GetItem
- }
- TaskInfo task;
- if (!readPythonProtobuf(taskObj, &task)) {
- PyErr_Format(PyExc_Exception,
- "Could not deserialize Python TaskInfo");
- return NULL;
- }
- tasks.push_back(task);
- }
-
- if (filtersObj != NULL) {
- if (!readPythonProtobuf(filtersObj, &filters)) {
- PyErr_Format(PyExc_Exception,
- "Could not deserialize Python Filters");
- return NULL;
- }
- }
-
- Status status = self->driver->launchTasks(offerIds, tasks, filters);
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_killTask(MesosSchedulerDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- PyObject* tidObj = NULL;
- TaskID tid;
- if (!PyArg_ParseTuple(args, "O", &tidObj)) {
- return NULL;
- }
- if (!readPythonProtobuf(tidObj, &tid)) {
- PyErr_Format(PyExc_Exception, "Could not deserialize Python TaskID");
- return NULL;
- }
-
- Status status = self->driver->killTask(tid);
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_declineOffer(MesosSchedulerDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- PyObject* offerIdObj = NULL;
- PyObject* filtersObj = NULL;
- OfferID offerId;
- Filters filters;
-
- if (!PyArg_ParseTuple(args, "O|O", &offerIdObj, &filtersObj)) {
- return NULL;
- }
-
- if (!readPythonProtobuf(offerIdObj, &offerId)) {
- PyErr_Format(PyExc_Exception, "Could not deserialize Python OfferID");
- return NULL;
- }
-
- if (filtersObj != NULL) {
- if (!readPythonProtobuf(filtersObj, &filters)) {
- PyErr_Format(PyExc_Exception,
- "Could not deserialize Python Filters");
- return NULL;
- }
- }
-
- Status status = self->driver->declineOffer(offerId, filters);
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_reviveOffers(MesosSchedulerDriverImpl* self)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- Status status = self->driver->reviveOffers();
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_sendFrameworkMessage(
- MesosSchedulerDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- PyObject* slaveIdObj = NULL;
- PyObject* executorIdObj = NULL;
- SlaveID slaveId;
- ExecutorID executorId;
- const char* data;
- int length;
-
- if (!PyArg_ParseTuple(
- args, "OOs#", &executorIdObj, &slaveIdObj, &data, &length)) {
- return NULL;
- }
-
- if (!readPythonProtobuf(executorIdObj, &executorId)) {
- PyErr_Format(PyExc_Exception, "Could not deserialize Python ExecutorID");
- return NULL;
- }
-
- if (!readPythonProtobuf(slaveIdObj, &slaveId)) {
- PyErr_Format(PyExc_Exception, "Could not deserialize Python SlaveID");
- return NULL;
- }
-
- Status status = self->driver->sendFrameworkMessage(
- executorId, slaveId, string(data, length));
-
- return PyInt_FromLong(status); // Sets exception if creating long fails.
-}
-
-
-PyObject* MesosSchedulerDriverImpl_reconcileTasks(
- MesosSchedulerDriverImpl* self,
- PyObject* args)
-{
- if (self->driver == NULL) {
- PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is NULL");
- return NULL;
- }
-
- PyObject* statusesObj = NULL;
- vector<TaskStatus> statuses;
-
- if (!PyArg_ParseTuple(args, "O", &statusesObj)) {
- return NULL;
- }
-
- if (!PyList_Check(statusesObj)) {
- PyErr_Format(PyExc_Exception,
- "Parameter 1 to reconcileTasks is not a list");
-
- return NULL;
- }
-
- Py_ssize_t len = PyList_Size(statusesObj);
- for (int i = 0; i < len; i++) {
- PyObject* statusObj = PyList_GetItem(statusesObj, i);
- if (statusObj == NULL) {
- return NULL;
- }
-
- TaskStatus status;
- if (!readPythonProtobuf(statusObj, &status)) {
- PyErr_Format(PyExc_Exception,
- "Could not deserialize Python TaskStatus");
- return NULL;
- }
- statuses.push_back(status);
- }
-
- Status status = self->driver->reconcileTasks(statuses);
- return PyInt_FromLong(status);
-}
-
-} // namespace python {
-} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/c5a68be1/src/python/native/mesos_scheduler_driver_impl.hpp
----------------------------------------------------------------------
diff --git a/src/python/native/mesos_scheduler_driver_impl.hpp
b/src/python/native/mesos_scheduler_driver_impl.hpp
deleted file mode 100644
index 8c285ae..0000000
--- a/src/python/native/mesos_scheduler_driver_impl.hpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MESOS_SCHEDULER_DRIVER_IMPL_HPP
-#define MESOS_SCHEDULER_DRIVER_IMPL_HPP
-
-#include <mesos/scheduler.hpp>
-
-
-namespace mesos { namespace python {
-
-class ProxyScheduler;
-
-/**
- * Python object structure for MesosSchedulerDriverImpl objects.
- */
-struct MesosSchedulerDriverImpl {
- PyObject_HEAD
- /* Type-specific fields go here. */
- MesosSchedulerDriver* driver;
- ProxyScheduler* proxyScheduler;
- PyObject* pythonScheduler;
-};
-
-/**
- * Python type object for MesosSchedulerDriverImpl.
- */
-extern PyTypeObject MesosSchedulerDriverImplType;
-
-/**
- * List of Python methods in MesosSchedulerDriverImpl.
- */
-extern PyMethodDef MesosSchedulerDriverImpl_methods[];
-
-/**
- * Create, but don't initialize, a new MesosSchedulerDriverImpl
- * (called by Python before init method).
- */
-PyObject* MesosSchedulerDriverImpl_new(PyTypeObject *type,
- PyObject *args,
- PyObject *kwds);
-
-/**
- * Initialize a MesosSchedulerDriverImpl with constructor arguments.
- */
-int MesosSchedulerDriverImpl_init(MesosSchedulerDriverImpl *self,
- PyObject *args,
- PyObject *kwds);
-
-/**
- * Free a MesosSchedulerDriverImpl.
- */
-void MesosSchedulerDriverImpl_dealloc(MesosSchedulerDriverImpl* self);
-
-/**
- * Traverse fields of a MesosSchedulerDriverImpl on a cyclic GC search.
- * See http://docs.python.org/extending/newtypes.html.
- */
-int MesosSchedulerDriverImpl_traverse(MesosSchedulerDriverImpl* self,
- visitproc visit,
- void* arg);
-/**
- * Clear fields of a MesosSchedulerDriverImpl that can participate in
- * GC cycles. See http://docs.python.org/extending/newtypes.html.
- */
-int MesosSchedulerDriverImpl_clear(MesosSchedulerDriverImpl* self);
-
-// MesosSchedulerDriverImpl methods
-PyObject* MesosSchedulerDriverImpl_start(MesosSchedulerDriverImpl* self);
-
-PyObject* MesosSchedulerDriverImpl_stop(
- MesosSchedulerDriverImpl* self,
- PyObject* args);
-
-PyObject* MesosSchedulerDriverImpl_abort(MesosSchedulerDriverImpl* self);
-
-PyObject* MesosSchedulerDriverImpl_join(MesosSchedulerDriverImpl* self);
-
-PyObject* MesosSchedulerDriverImpl_run(MesosSchedulerDriverImpl* self);
-
-PyObject* MesosSchedulerDriverImpl_requestResources(
- MesosSchedulerDriverImpl* self,
- PyObject* args);
-
-PyObject* MesosSchedulerDriverImpl_launchTasks(
- MesosSchedulerDriverImpl* self,
- PyObject* args);
-
-PyObject* MesosSchedulerDriverImpl_killTask(
- MesosSchedulerDriverImpl* self,
- PyObject* args);
-
-PyObject* MesosSchedulerDriverImpl_declineOffer(
- MesosSchedulerDriverImpl* self,
- PyObject* args);
-
-PyObject* MesosSchedulerDriverImpl_reviveOffers(MesosSchedulerDriverImpl*
self);
-
-PyObject* MesosSchedulerDriverImpl_sendFrameworkMessage(
- MesosSchedulerDriverImpl* self,
- PyObject* args);
-
-PyObject* MesosSchedulerDriverImpl_reconcileTasks(
- MesosSchedulerDriverImpl* self,
- PyObject* args);
-
-} // namespace python {
-} // namespace mesos {
-
-#endif /* MESOS_SCHEDULER_DRIVER_IMPL_HPP */