diff --git a/.gitignore b/.gitignore index b499e0894c35c95d989660ac54f6b1eddbeaadb3..f9fb1f27c705a33f569ae7ee3e2547a60c55abc5 100644 --- a/.gitignore +++ b/.gitignore @@ -43,9 +43,9 @@ _obj /aclocal.m4 /ltmain.sh /ylwrap +/client/kresc /doc/doxyxml /doc/html -/daemon/kresc /daemon/kresd /daemon/lua/*.inc /daemon/lua/kres.lua diff --git a/Makefile b/Makefile index 3a177936af90c7ec4794ef2de7c58902a4347c63..1d3cc8a9cd4c2d96e8bff3a7d3587342ca37ff82 100644 --- a/Makefile +++ b/Makefile @@ -187,6 +187,7 @@ $(DESTDIR)$(ETCDIR): # Sub-targets include contrib/contrib.mk include lib/lib.mk +include client/client.mk include daemon/daemon.mk include modules/modules.mk include tests/tests.mk diff --git a/NEWS b/NEWS index f27af15673d130eb64b82a2fcc4cd0d44797c90b..0855cd0130955e28084aed6db50d336345cd00e0 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +Knot Resolver 2.0.0 (2018-xx-yy) +================================ +Incompatible changes +-------------------- +- script supervisor.py was removed, please migrate to a real process manager +- module ketcd was renamed to etcd for consistency +- module kmemcached was renamed to memcached for consistency + Knot Resolver 1.5.1 (2017-1x-yy) ================================ diff --git a/client/client.mk b/client/client.mk new file mode 100644 index 0000000000000000000000000000000000000000..07508aa305f476c48037f48215b897f3869075ec --- /dev/null +++ b/client/client.mk @@ -0,0 +1,14 @@ +# Experimental client requires libedit + +ifeq ($(HAS_libedit), yes) +kresc_SOURCES := client/kresc.c +kresc_CFLAGS += -fPIE $(libedit_CFLAGS) +kresc_LIBS += $(contrib_TARGET) $(libedit_LIBS) +kresc_DEPEND := $(libkres) $(contrib) +$(eval $(call make_sbin,kresc,client,yes)) +client: $(kresc) +client-install: kresc-install +client-clean: kresc-clean + +.PHONY: client client-install client-clean +endif diff --git a/daemon/kresc.c b/client/kresc.c similarity index 98% rename from daemon/kresc.c rename to client/kresc.c index 9baccf3c61e6d463e95e74e5391276ae21cfe156..88a48808c21e040d63c8c3b68f137b18234129f2 100644 --- a/daemon/kresc.c +++ b/client/kresc.c @@ -453,6 +453,8 @@ static int interact() int main(int argc, char **argv) { + fprintf(stderr, "Warning! %s is highly experimental, use at own risk.\n", argv[0]); + fprintf(stderr, "Please tell authors what features you expect from client utility.\n"); if (argc != 2) { fprintf(stderr, "Usage: %s tty/xxxxx\n", argv[0]); return 1; diff --git a/daemon/README.rst b/daemon/README.rst index 4e00214f7688705f6cc1547fd65861792838d0ca..1d891e6c4a78544e3b6927e7b223944e0d994316 100644 --- a/daemon/README.rst +++ b/daemon/README.rst @@ -83,6 +83,13 @@ You can also toggle it on runtime with ``verbose(true|false)`` command. $ kresd -v +To run the daemon by hand, such as under ``nohup``, use ``-f 1`` to start a single fork. For example: + +.. code-block:: bash + + $ nohup ./daemon/kresd -a 127.0.0.1 -f 1 -v & + + Scaling out =========== @@ -108,7 +115,7 @@ You can add, start and stop processes during runtime based on the load. .. _daemon-reuseport: -.. note:: On recent Linux supporting ``SO_REUSEPORT`` (since 3.9, backported to RHEL 2.6.32) it is also able to bind to the same endpoint and distribute the load between the forked processes. If your OS doesn't support it, you can :ref:`use supervisor <daemon-supervised>` that is going to bind to sockets before starting multiple processes. +.. note:: On recent Linux supporting ``SO_REUSEPORT`` (since 3.9, backported to RHEL 2.6.32) it is also able to bind to the same endpoint and distribute the load between the forked processes. If your OS doesn't support it, use only one daemon process. Notice the absence of an interactive CLI. You can attach to the the consoles for each process, they are in ``rundir/tty/PID``. @@ -131,26 +138,10 @@ Running supervised Knot Resolver can run under a supervisor to allow for graceful restarts, watchdog process and socket activation. This way the supervisor binds to sockets and lends them to the resolver daemon. If the resolver terminates or is killed, the sockets remain open and no queries are dropped. -The watchdog process must notify kresd about active file descriptors, and kresd will automatically determine the socket type and bound address, thus it will appear as any other address. There's a tiny supervisor script for convenience, but you should have a look at `real process managers`_. - -.. code-block:: bash - - $ python scripts/supervisor.py ./daemon/kresd -a 127.0.0.1 - $ [system] interactive mode - > quit() - > [2016-03-28 16:06:36.795879] process finished, pid = 99342, status = 0, uptime = 0:00:01.720612 - [system] interactive mode - > +The watchdog process must notify kresd about active file descriptors, and kresd will automatically determine the socket type and bound address, thus it will appear as any other address. You should have a look at `real process managers`_. The daemon also supports `systemd socket activation`_, it is automatically detected and requires no configuration on users's side. -To run the daemon by hand, such as under ``nohup``, use ``-f 1`` to start a single fork. For example: - -.. code-block:: bash - - $ nohup ./daemon/kresd -a 127.0.0.1 -f 1 & - - Configuration ============= diff --git a/daemon/daemon.mk b/daemon/daemon.mk index 09717d22b7301c64007bc41ce7b74cffe80169af..d1cef6c22847b3ac457de96064069c748ce6aa65 100644 --- a/daemon/daemon.mk +++ b/daemon/daemon.mk @@ -77,16 +77,4 @@ daemon/lua/kres-gen.lua: | $(libkres) daemon/lua/kres-gen.sh | sed 's/ /\t/g' > $@ .DELETE_ON_ERROR: daemon/lua/kres-gen.lua -# Client -ifeq ($(HAS_libedit), yes) -kresc_SOURCES := daemon/kresc.c -kresc_CFLAGS += -fPIE $(libedit_CFLAGS) -kresc_LIBS += $(contrib_TARGET) $(libedit_LIBS) -kresc_DEPEND := $(libkres) $(contrib) -$(eval $(call make_sbin,kresc,daemon,yes)) -client: $(kresc) -client-install: kresc-install -client-clean: kresc-clean -endif - -.PHONY: daemon daemon-install daemon-clean client client-install client-clean +.PHONY: daemon daemon-install daemon-clean diff --git a/doc/modules.rst b/doc/modules.rst index d3c5eec1c63d727b788b9fe111a3e89af106fac5..709fee8ed0b3edec4d3999c46c7953e95ca0cb93 100644 --- a/doc/modules.rst +++ b/doc/modules.rst @@ -16,9 +16,9 @@ Knot DNS Resolver modules .. include:: ../modules/http/README.rst .. include:: ../modules/daf/README.rst .. include:: ../modules/graphite/README.rst -.. include:: ../modules/kmemcached/README.rst +.. include:: ../modules/memcached/README.rst .. include:: ../modules/redis/README.rst -.. include:: ../modules/ketcd/README.rst +.. include:: ../modules/etcd/README.rst .. include:: ../modules/dns64/README.rst .. include:: ../modules/renumber/README.rst .. include:: ../modules/cookies/README.rst diff --git a/modules/ketcd/README.rst b/modules/etcd/README.rst similarity index 98% rename from modules/ketcd/README.rst rename to modules/etcd/README.rst index a3803deb3284815d1e292883d1b97b7b89e448c7..d25b369a4c3bceddd78cd211715ebb82efdd3cf0 100644 --- a/modules/ketcd/README.rst +++ b/modules/etcd/README.rst @@ -27,7 +27,7 @@ Example configuration .. code-block:: lua modules = { - ketcd = { + etcd = { prefix = '/kresd', peer = 'http://127.0.0.1:7001' } diff --git a/modules/ketcd/ketcd.lua b/modules/etcd/etcd.lua similarity index 58% rename from modules/ketcd/ketcd.lua rename to modules/etcd/etcd.lua index 018704c6e954379147365238d2b2c792eeca64c5..08348529dac9e394d4badff2936a9dda418063c0 100644 --- a/modules/ketcd/ketcd.lua +++ b/modules/etcd/etcd.lua @@ -1,5 +1,5 @@ ---- @module ketcd -local ketcd = {} +--- @module etcd +local etcd = {} -- @function update subtree configuration local function update_subtree(tree) @@ -17,39 +17,39 @@ local function update_subtree(tree) end -- @function reload whole configuration -function ketcd.reload() - local res, err = ketcd.cli:readdir('/', true) +function etcd.reload() + local res, err = etcd.cli:readdir('/', true) if err then error(err) end update_subtree(res.body.node.nodes) end -function ketcd.init() - ketcd.Etcd = require('etcd.luasocket') - ketcd.defaults = { prefix = '/kresd' } +function etcd.init() + etcd.Etcd = require('etcd.luasocket') + etcd.defaults = { prefix = '/kresd' } end -function ketcd.deinit() - if ketcd.ev then event.cancel(ketcd.ev) end +function etcd.deinit() + if etcd.ev then event.cancel(etcd.ev) end end -function ketcd.config(conf) - local options = ketcd.defaults +function etcd.config(conf) + local options = etcd.defaults if type(conf) == 'table' then for k,v in pairs(conf) do options[k] = v end end -- create connection - local cli, err = ketcd.Etcd.new(options) + local cli, err = etcd.Etcd.new(options) if err then error(err) end - ketcd.cli = cli + etcd.cli = cli -- schedule recurrent polling -- @todo: the etcd has watch() API, but this requires -- coroutines on socket operations - if ketcd.ev then event.cancel(ketcd.ev) end - ketcd.ev = event.recurrent(5 * sec, ketcd.reload) + if etcd.ev then event.cancel(etcd.ev) end + etcd.ev = event.recurrent(5 * sec, etcd.reload) end -return ketcd +return etcd diff --git a/modules/etcd/etcd.mk b/modules/etcd/etcd.mk new file mode 100644 index 0000000000000000000000000000000000000000..0b8d2448620ffd3fe0aa0f9dcfd1ad9d2ba8446b --- /dev/null +++ b/modules/etcd/etcd.mk @@ -0,0 +1,2 @@ +etcd_SOURCES := etcd.lua +$(call make_lua_module,etcd) diff --git a/modules/ketcd/ketcd.mk b/modules/ketcd/ketcd.mk deleted file mode 100644 index 8fa61d713780a3e9004df32b6d9e77e554e8acaf..0000000000000000000000000000000000000000 --- a/modules/ketcd/ketcd.mk +++ /dev/null @@ -1,2 +0,0 @@ -ketcd_SOURCES := ketcd.lua -$(call make_lua_module,ketcd) diff --git a/modules/kmemcached/kmemcached.mk b/modules/kmemcached/kmemcached.mk deleted file mode 100644 index 24c0ac604608d8ae78d5c82399a4a4bac7ac9bcd..0000000000000000000000000000000000000000 --- a/modules/kmemcached/kmemcached.mk +++ /dev/null @@ -1,5 +0,0 @@ -kmemcached_CFLAGS := -fvisibility=hidden -fPIC -kmemcached_SOURCES := modules/kmemcached/kmemcached.c modules/kmemcached/cdb_memcached.c -kmemcached_DEPEND := $(libkres) -kmemcached_LIBS := $(libkres_TARGET) $(libkres_LIBS) $(libmemcached_LIBS) -$(call make_c_module,kmemcached) diff --git a/modules/kmemcached/README.rst b/modules/memcached/README.rst similarity index 98% rename from modules/kmemcached/README.rst rename to modules/memcached/README.rst index dd0b1102f03d1cf9f5caed6e2ac51ad07df3e1ca..331c126bb9e031aa737dab730460eaff453b1f2d 100644 --- a/modules/kmemcached/README.rst +++ b/modules/memcached/README.rst @@ -8,7 +8,7 @@ After loading you can see the storage backend registered and useable. .. code-block:: lua - > modules.load 'kmemcached' + > modules.load 'memcached' > cache.backends() [memcached://] => true diff --git a/modules/kmemcached/cdb_memcached.c b/modules/memcached/cdb_memcached.c similarity index 100% rename from modules/kmemcached/cdb_memcached.c rename to modules/memcached/cdb_memcached.c diff --git a/modules/kmemcached/kmemcached.c b/modules/memcached/memcached.c similarity index 100% rename from modules/kmemcached/kmemcached.c rename to modules/memcached/memcached.c diff --git a/modules/memcached/memcached.mk b/modules/memcached/memcached.mk new file mode 100644 index 0000000000000000000000000000000000000000..2eaa57c30e48a8f1c55d8ba319022d67a4e0492e --- /dev/null +++ b/modules/memcached/memcached.mk @@ -0,0 +1,5 @@ +memcached_CFLAGS := -fvisibility=hidden -fPIC +memcached_SOURCES := modules/memcached/memcached.c modules/memcached/cdb_memcached.c +memcached_DEPEND := $(libkres) +memcached_LIBS := $(libkres_TARGET) $(libkres_LIBS) $(libmemcached_LIBS) +$(call make_c_module,memcached) diff --git a/modules/modules.mk b/modules/modules.mk index 6734b6c3fd0e7184628f2796d5054e13775da37e..23d597d116d4cdb3757a85f330a17684116fdd93 100644 --- a/modules/modules.mk +++ b/modules/modules.mk @@ -13,7 +13,7 @@ endif # Memcached ifeq ($(HAS_libmemcached),yes) -modules_TARGETS += kmemcached +modules_TARGETS += memcached endif # Redis ifeq ($(HAS_hiredis),yes) @@ -22,7 +22,7 @@ endif # List of Lua modules ifeq ($(HAS_lua),yes) -modules_TARGETS += ketcd \ +modules_TARGETS += etcd \ graphite \ policy \ view \ diff --git a/scripts/inet_pton.py b/scripts/inet_pton.py index 30bf06af64fae59e8d98d903105c73d500d77ed3..6eea32ac22b1618dbc736a7d6ded2d1bfdd6affa 100755 --- a/scripts/inet_pton.py +++ b/scripts/inet_pton.py @@ -1,19 +1,20 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 +""" +Print IP address to binary representation in Python hex format \x12 +""" -from socket import inet_pton,AF_INET6,AF_INET +from socket import inet_pton, AF_INET6, AF_INET import sys from binascii import hexlify -from string import find -if find(sys.argv[1], ":") == -1: - addr_type = AF_INET -else: - addr_type = AF_INET6 - -x = hexlify(inet_pton(addr_type, sys.argv[1])) +try: + arg = sys.argv[1] +except: + sys.exit('Usage: inet_pton.py <IPv4 or IPv6 address>') -out = "" -for i in range(0, len(x) / 2): - out += "\\x" + x[i*2] + x[i*2+1] +if ':' in arg: + addr_type = AF_INET6 +else: + addr_type = AF_INET -print out +print(repr(inet_pton(addr_type, arg)).strip("'")) diff --git a/scripts/supervisor.py b/scripts/supervisor.py deleted file mode 100755 index 218eb522394b6a2f3f119391802fc37d025f6c68..0000000000000000000000000000000000000000 --- a/scripts/supervisor.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python -# -# This is an example of simple supervisor process owning bound sockets and -# handing them over to supervised process, allowing for graceful restarts. -# -import time, datetime -import socket -import os, sys - -# Help -def help(): - print('Usage: %s <bin> addr@port ...' % sys.argv[0]) - print('Example: python scripts/supervisor.py ./daemon/kresd -a 127.0.0.1') - sys.exit(1) -if len(sys.argv) < 3: - help() -# Bind to sockets -args = [] -unparsed = sys.argv[1:] -sockets = [] -while len(unparsed) > 0: - tok = unparsed.pop(0) - # Rewrite '-a' only, copy otherwise - if tok != '-a': - args.append(tok) - continue - # Parse address - addr = unparsed.pop(0) - try: - if '@' in addr: - addr, port = addr.split('@') - port = int(port) - elif '#' in addr: - addr, port = addr.split('#') - port = int(port) - else: - port = 53 - except: help() - # Open TCP socket - family = socket.AF_INET6 if ':' in addr else socket.AF_INET - tcp = socket.socket(family, socket.SOCK_STREAM) - tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - tcp.bind((addr, port)) - tcp.listen(16) - sockets.append(tcp) - # Open UDP socket - udp = socket.socket(family, socket.SOCK_DGRAM) - udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - udp.bind((addr, port)) - sockets.append(udp) -args = args + ['-S %d' % s.fileno() for s in sockets] -while True: # Fork forever - pid = os.fork() - if pid == 0: - os.execv(args[0], args) - else: # Wait for fork to die - start = datetime.datetime.now() - _, status = os.waitpid(pid, 0) - end = datetime.datetime.now() - print('[%s] process finished, pid = %d, status = %d, uptime = %s' % \ - (start, pid, status, end - start)) - time.sleep(0.5)