BIND 10 trac2853, updated. f26eae2533b0b2c6591ad6aa9116dc9ba00c462a [2853] Add Python wrapper for getCachedZoneWriter()
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Jun 5 11:39:36 UTC 2013
The branch, trac2853 has been updated
via f26eae2533b0b2c6591ad6aa9116dc9ba00c462a (commit)
via 70c715efff4255744322403c03a7be1e64d99c5e (commit)
via 6a4ee80ea2995124b737bd718f16f1baadb5c7dd (commit)
from 508e3554d5167a27ed1287a3903f851bfaf11a17 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit f26eae2533b0b2c6591ad6aa9116dc9ba00c462a
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Jun 5 17:03:54 2013 +0530
[2853] Add Python wrapper for getCachedZoneWriter()
commit 70c715efff4255744322403c03a7be1e64d99c5e
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Jun 5 16:28:36 2013 +0530
[2853] Wrap to 79 cols
commit 6a4ee80ea2995124b737bd718f16f1baadb5c7dd
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Jun 5 16:28:09 2013 +0530
[2853] Add shell of ZoneWriter class
In the context of Python bindings, ZoneWriter cannot be directly
constructed and must be obtained using getCachedZoneWriter() on a
ConfigurableClientList.
-----------------------------------------------------------------------
Summary of changes:
src/lib/datasrc/client_list.h | 3 +-
src/lib/python/isc/datasrc/Makefile.am | 1 +
.../isc/datasrc/configurableclientlist_python.cc | 85 ++++++++++-
.../zonewriter_python.cc} | 156 +++++++++++---------
.../{finder_python.h => zonewriter_python.h} | 30 ++--
5 files changed, 184 insertions(+), 91 deletions(-)
copy src/lib/python/isc/{acl/dns_requestacl_python.cc => datasrc/zonewriter_python.cc} (58%)
copy src/lib/python/isc/datasrc/{finder_python.h => zonewriter_python.h} (61%)
-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/client_list.h b/src/lib/datasrc/client_list.h
index 7917f3f..e8082ee 100644
--- a/src/lib/datasrc/client_list.h
+++ b/src/lib/datasrc/client_list.h
@@ -379,10 +379,9 @@ public:
memory::ZoneTableSegment::MemorySegmentOpenMode mode,
isc::data::ConstElementPtr config_params);
-private:
/// \brief Convenience type shortcut
typedef boost::shared_ptr<memory::ZoneWriter> ZoneWriterPtr;
-public:
+
/// \brief Codes indicating in-memory cache status for a given zone name.
///
/// This is used as a result of the getCachedZoneWriter() method.
diff --git a/src/lib/python/isc/datasrc/Makefile.am b/src/lib/python/isc/datasrc/Makefile.am
index 28c87ac..36f17fd 100644
--- a/src/lib/python/isc/datasrc/Makefile.am
+++ b/src/lib/python/isc/datasrc/Makefile.am
@@ -21,6 +21,7 @@ datasrc_la_SOURCES += journal_reader_python.cc journal_reader_python.h
datasrc_la_SOURCES += configurableclientlist_python.cc
datasrc_la_SOURCES += configurableclientlist_python.h
datasrc_la_SOURCES += zone_loader_python.cc zone_loader_python.h
+datasrc_la_SOURCES += zonewriter_python.cc zonewriter_python.h
datasrc_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
datasrc_la_CXXFLAGS = $(AM_CXXFLAGS) $(PYTHON_CXXFLAGS)
diff --git a/src/lib/python/isc/datasrc/configurableclientlist_python.cc b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
index 875d7e0..47cab01 100644
--- a/src/lib/python/isc/datasrc/configurableclientlist_python.cc
+++ b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
@@ -35,12 +35,14 @@
#include "datasrc.h"
#include "finder_python.h"
#include "client_python.h"
+#include "zonewriter_python.h"
using namespace std;
using namespace isc::util::python;
using namespace isc::datasrc;
using namespace isc::datasrc::memory;
using namespace isc::datasrc::python;
+using namespace isc::datasrc::memory::python;
using namespace isc::dns::python;
//
@@ -67,7 +69,8 @@ ConfigurableClientList_init(PyObject* po_self, PyObject* args, PyObject*) {
return (0);
}
} catch (const exception& ex) {
- const string ex_what = "Failed to construct ConfigurableClientList object: " +
+ const string ex_what =
+ "Failed to construct ConfigurableClientList object: " +
string(ex.what());
PyErr_SetString(getDataSourceException("Error"), ex_what.c_str());
return (-1);
@@ -152,6 +155,47 @@ ConfigurableClientList_resetMemorySegment(PyObject* po_self, PyObject* args) {
}
PyObject*
+ConfigurableClientList_getCachedZoneWriter(PyObject* po_self, PyObject* args) {
+ s_ConfigurableClientList* self =
+ static_cast<s_ConfigurableClientList*>(po_self);
+ try {
+ PyObject* name_obj;
+ const char* datasrc_name_p = "";
+ if (PyArg_ParseTuple(args, "O!|s", &isc::dns::python::name_type,
+ &name_obj, &datasrc_name_p)) {
+ const isc::dns::Name
+ name(isc::dns::python::PyName_ToName(name_obj));
+ const std::string datasrc_name(datasrc_name_p);
+
+ const ConfigurableClientList::ZoneWriterPair result =
+ self->cppobj->getCachedZoneWriter(name, datasrc_name);
+
+ PyObjectContainer writer;
+ if (!result.second) {
+ // Use the Py_BuildValue, as it takes care of the
+ // reference counts correctly.
+ writer.reset(Py_BuildValue(""));
+ } else {
+ // Make sure it keeps the writer alive.
+ writer.reset(createZoneWriterObject(result.second,
+ writer.get()));
+ }
+
+ return (Py_BuildValue("IO", result.first, writer.get()));
+ } else {
+ return (NULL);
+ }
+ } catch (const std::exception& exc) {
+ PyErr_SetString(getDataSourceException("Error"), exc.what());
+ return (NULL);
+ } catch (...) {
+ PyErr_SetString(getDataSourceException("Error"),
+ "Unknown C++ exception");
+ return (NULL);
+ }
+}
+
+PyObject*
ConfigurableClientList_find(PyObject* po_self, PyObject* args) {
s_ConfigurableClientList* self =
static_cast<s_ConfigurableClientList*>(po_self);
@@ -240,6 +284,17 @@ Parameters:\n\
datasrc_name The name of the data source whose segment to reset.\
mode The open mode for the new memory segment.\
config_params The configuration for the new memory segment, as a JSON encoded string." },
+ { "get_cached_zone_writer", ConfigurableClientList_getCachedZoneWriter,
+ METH_VARARGS,
+ "get_cached_zone_writer(zone, datasrc_name) -> status, zone_writer\n\
+\n\
+Wrapper around C++ ConfigurableClientList::getCachedZoneWriter\n\
+\n\
+This returns a ZoneWriter that can be used to (re)load a zone.\n\
+\n\
+Parameters:\n\
+ zone The name of the zone to (re)load.\
+ datasrc_name The name of the data source where the zone is to be loaded." },
{ "find", ConfigurableClientList_find, METH_VARARGS,
"find(zone, want_exact_match=False, want_finder=True) -> datasrc_client,\
zone_finder, exact_match\n\
@@ -349,11 +404,31 @@ initModulePart_ConfigurableClientList(PyObject* mod) {
}
Py_INCREF(&configurableclientlist_type);
- // FIXME: These should eventually be moved to the ZoneTableSegment
- // class when we add Python bindings for the memory data source
- // specific bits. But for now, we add these enums here to support
- // reloading a zone table segment.
try {
+ // ConfigurableClientList::CacheStatus enum
+ installClassVariable(configurableclientlist_type,
+ "CACHE_STATUS_CACHE_DISABLED",
+ Py_BuildValue("I", ConfigurableClientList::CACHE_DISABLED));
+ installClassVariable(configurableclientlist_type,
+ "CACHE_STATUS_ZONE_NOT_CACHED",
+ Py_BuildValue("I", ConfigurableClientList::ZONE_NOT_CACHED));
+ installClassVariable(configurableclientlist_type,
+ "CACHE_STATUS_ZONE_NOT_FOUND",
+ Py_BuildValue("I", ConfigurableClientList::ZONE_NOT_FOUND));
+ installClassVariable(configurableclientlist_type,
+ "CACHE_STATUS_CACHE_NOT_WRITABLE",
+ Py_BuildValue("I", ConfigurableClientList::CACHE_NOT_WRITABLE));
+ installClassVariable(configurableclientlist_type,
+ "CACHE_STATUS_DATASRC_NOT_FOUND",
+ Py_BuildValue("I", ConfigurableClientList::DATASRC_NOT_FOUND));
+ installClassVariable(configurableclientlist_type,
+ "CACHE_STATUS_ZONE_SUCCESS",
+ Py_BuildValue("I", ConfigurableClientList::ZONE_SUCCESS));
+
+ // FIXME: These should eventually be moved to the
+ // ZoneTableSegment class when we add Python bindings for the
+ // memory data source specific bits. But for now, we add these
+ // enums here to support reloading a zone table segment.
installClassVariable(configurableclientlist_type, "CREATE",
Py_BuildValue("I", ZoneTableSegment::CREATE));
installClassVariable(configurableclientlist_type, "READ_WRITE",
diff --git a/src/lib/python/isc/datasrc/zonewriter_python.cc b/src/lib/python/isc/datasrc/zonewriter_python.cc
new file mode 100644
index 0000000..93e0fe0
--- /dev/null
+++ b/src/lib/python/isc/datasrc/zonewriter_python.cc
@@ -0,0 +1,196 @@
+// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// Enable this if you use s# variants with PyArg_ParseTuple(), see
+// http://docs.python.org/py3k/c-api/arg.html#strings-and-buffers
+//#define PY_SSIZE_T_CLEAN
+
+// Python.h needs to be placed at the head of the program file, see:
+// http://docs.python.org/py3k/extending/extending.html#a-simple-example
+#include <Python.h>
+
+#include <string>
+#include <stdexcept>
+
+#include <util/python/pycppwrapper_util.h>
+
+#include <datasrc/memory/zone_writer.h>
+
+#include "zonewriter_python.h"
+
+using namespace std;
+using namespace isc::util::python;
+using namespace isc::datasrc;
+using namespace isc::datasrc::memory;
+using namespace isc::datasrc::memory::python;
+
+//
+// ZoneWriter
+//
+
+namespace {
+
+// The s_* Class simply covers one instantiation of the object
+class s_ZoneWriter : public PyObject {
+public:
+ s_ZoneWriter() :
+ cppobj(ConfigurableClientList::ZoneWriterPtr()),
+ base_obj(NULL)
+ {}
+
+ ConfigurableClientList::ZoneWriterPtr cppobj;
+ // This is a reference to a base object; if the object of this class
+ // depends on another object to be in scope during its lifetime,
+ // we use INCREF the base object upon creation, and DECREF it at
+ // the end of the destructor
+ // This is an optional argument to createXXX(). If NULL, it is ignored.
+ PyObject* base_obj;
+};
+
+int
+ZoneWriter_init(PyObject*, PyObject*, PyObject*) {
+ // can't be called directly
+ PyErr_SetString(PyExc_TypeError,
+ "ZoneWriter cannot be constructed directly");
+
+ return (-1);
+}
+
+void
+ZoneWriter_destroy(PyObject* po_self) {
+ s_ZoneWriter* self = static_cast<s_ZoneWriter*>(po_self);
+ // cppobj is a shared ptr, but to make sure things are not destroyed in
+ // the wrong order, we reset it here.
+ self->cppobj.reset();
+ if (self->base_obj != NULL) {
+ Py_DECREF(self->base_obj);
+ }
+ Py_TYPE(self)->tp_free(self);
+}
+
+// This list contains the actual set of functions we have in
+// python. Each entry has
+// 1. Python method name
+// 2. Our static function here
+// 3. Argument type
+// 4. Documentation
+PyMethodDef ZoneWriter_methods[] = {
+ { NULL, NULL, 0, NULL }
+};
+
+const char* const ZoneWriter_doc = "\
+Does an update to a zone\n\
+\n\
+This represents the work of a (re)load of a zone. The work is divided\n\
+into three stages -- load(), install() and cleanup(). They should\n\
+be called in this order for the effect to take place.\n\
+";
+
+} // end of unnamed namespace
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+namespace python {
+// This defines the complete type for reflection in python and
+// parsing of PyObject* to s_ZoneWriter
+// Most of the functions are not actually implemented and NULL here.
+PyTypeObject zonewriter_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "datasrc.ZoneWriter",
+ sizeof(s_ZoneWriter), // tp_basicsize
+ 0, // tp_itemsize
+ ZoneWriter_destroy, // tp_dealloc
+ NULL, // tp_print
+ NULL, // tp_getattr
+ NULL, // tp_setattr
+ NULL, // tp_reserved
+ NULL, // tp_repr
+ NULL, // tp_as_number
+ NULL, // tp_as_sequence
+ NULL, // tp_as_mapping
+ NULL, // tp_hash
+ NULL, // tp_call
+ NULL, // tp_str
+ NULL, // tp_getattro
+ NULL, // tp_setattro
+ NULL, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ ZoneWriter_doc,
+ NULL, // tp_traverse
+ NULL, // tp_clear
+ NULL, // tp_richcompare
+ 0, // tp_weaklistoffset
+ NULL, // tp_iter
+ NULL, // tp_iternext
+ ZoneWriter_methods, // tp_methods
+ NULL, // tp_members
+ NULL, // tp_getset
+ NULL, // tp_base
+ NULL, // tp_dict
+ NULL, // tp_descr_get
+ NULL, // tp_descr_set
+ 0, // tp_dictoffset
+ ZoneWriter_init, // tp_init
+ NULL, // tp_alloc
+ PyType_GenericNew, // tp_new
+ NULL, // tp_free
+ NULL, // tp_is_gc
+ NULL, // tp_bases
+ NULL, // tp_mro
+ NULL, // tp_cache
+ NULL, // tp_subclasses
+ NULL, // tp_weaklist
+ NULL, // tp_del
+ 0 // tp_version_tag
+};
+
+// Module Initialization, all statics are initialized here
+bool
+initModulePart_ZoneWriter(PyObject* mod) {
+ // We initialize the static description object with PyType_Ready(),
+ // then add it to the module. This is not just a check! (leaving
+ // this out results in segmentation faults)
+ if (PyType_Ready(&zonewriter_type) < 0) {
+ return (false);
+ }
+ void* p = &zonewriter_type;
+ if (PyModule_AddObject(mod, "ZoneWriter", static_cast<PyObject*>(p)) < 0) {
+ return (false);
+ }
+ Py_INCREF(&zonewriter_type);
+
+ return (true);
+}
+
+PyObject*
+createZoneWriterObject(ConfigurableClientList::ZoneWriterPtr source,
+ PyObject* base_obj)
+{
+ s_ZoneWriter* py_zf = static_cast<s_ZoneWriter*>(
+ zonewriter_type.tp_alloc(&zonewriter_type, 0));
+ if (py_zf != NULL) {
+ py_zf->cppobj = source;
+ py_zf->base_obj = base_obj;
+ if (base_obj != NULL) {
+ Py_INCREF(base_obj);
+ }
+ }
+ return (py_zf);
+}
+
+} // namespace python
+} // namespace memory
+} // namespace datasrc
+} // namespace isc
diff --git a/src/lib/python/isc/datasrc/zonewriter_python.h b/src/lib/python/isc/datasrc/zonewriter_python.h
new file mode 100644
index 0000000..a7c97b3
--- /dev/null
+++ b/src/lib/python/isc/datasrc/zonewriter_python.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef PYTHON_ZONEWRITER_H
+#define PYTHON_ZONEWRITER_H 1
+
+#include <Python.h>
+#include <datasrc/client_list.h>
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+namespace python {
+
+extern PyTypeObject zonewriter_type;
+
+bool initModulePart_ZoneWriter(PyObject* mod);
+
+/// \brief Create a ZoneWriter python object
+///
+/// \param source The zone writer pointer to wrap
+/// \param base_obj An optional PyObject that this ZoneWriter depends on
+/// Its refcount is increased, and will be decreased when
+/// this zone iterator is destroyed, making sure that the
+/// base object is never destroyed before this ZoneWriter.
+PyObject* createZoneWriterObject(
+ isc::datasrc::ConfigurableClientList::ZoneWriterPtr source,
+ PyObject* base_obj = NULL);
+
+} // namespace python
+} // namespace memory
+} // namespace datasrc
+} // namespace isc
+
+#endif // PYTHON_ZONEWRITER_H
+
+// Local Variables:
+// mode: c++
+// End:
More information about the bind10-changes
mailing list