mirror of
https://github.com/openvswitch/ovs
synced 2025-10-21 14:49:41 +00:00
python: Add TCP passive-mode to IDL.
Requested-by: "D M, Vikas" <vikas.d-m@hpe.com> Requested-by: "Kamat, Maruti Haridas" <maruti.kamat@hpe.com> Requested-by: "Sukhdev Kapur" <sukhdev@arista.com> Requested-by: "Migliaccio, Armando" <armando.migliaccio@hpe.com> Signed-off-by: "Ofer Ben-Yacov" <ofer.benyacov@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
committed by
Ben Pfaff
parent
0cfd47f9dc
commit
af35823711
@@ -435,7 +435,7 @@ class Session(object):
|
|||||||
self.reconnect.connecting(ovs.timeval.msec())
|
self.reconnect.connecting(ovs.timeval.msec())
|
||||||
else:
|
else:
|
||||||
self.reconnect.connect_failed(ovs.timeval.msec(), error)
|
self.reconnect.connect_failed(ovs.timeval.msec(), error)
|
||||||
elif self.pstream is not None:
|
elif self.pstream is None:
|
||||||
error, self.pstream = ovs.stream.PassiveStream.open(name)
|
error, self.pstream = ovs.stream.PassiveStream.open(name)
|
||||||
if not error:
|
if not error:
|
||||||
self.reconnect.listening(ovs.timeval.msec())
|
self.reconnect.listening(ovs.timeval.msec())
|
||||||
|
@@ -269,9 +269,9 @@ class PassiveStream(object):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def is_valid_name(name):
|
def is_valid_name(name):
|
||||||
"""Returns True if 'name' is a passive stream name in the form
|
"""Returns True if 'name' is a passive stream name in the form
|
||||||
"TYPE:ARGS" and TYPE is a supported passive stream type (currently only
|
"TYPE:ARGS" and TYPE is a supported passive stream type (currently
|
||||||
"punix:"), otherwise False."""
|
"punix:" or "ptcp"), otherwise False."""
|
||||||
return name.startswith("punix:")
|
return name.startswith("punix:") | name.startswith("ptcp:")
|
||||||
|
|
||||||
def __init__(self, sock, name, bind_path):
|
def __init__(self, sock, name, bind_path):
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -282,8 +282,8 @@ class PassiveStream(object):
|
|||||||
def open(name):
|
def open(name):
|
||||||
"""Attempts to start listening for remote stream connections. 'name'
|
"""Attempts to start listening for remote stream connections. 'name'
|
||||||
is a connection name in the form "TYPE:ARGS", where TYPE is an passive
|
is a connection name in the form "TYPE:ARGS", where TYPE is an passive
|
||||||
stream class's name and ARGS are stream class-specific. Currently the
|
stream class's name and ARGS are stream class-specific. Currently the
|
||||||
only supported TYPE is "punix".
|
supported values for TYPE are "punix" and "ptcp".
|
||||||
|
|
||||||
Returns (error, pstream): on success 'error' is 0 and 'pstream' is the
|
Returns (error, pstream): on success 'error' is 0 and 'pstream' is the
|
||||||
new PassiveStream, on failure 'error' is a positive errno value and
|
new PassiveStream, on failure 'error' is a positive errno value and
|
||||||
@@ -294,10 +294,20 @@ class PassiveStream(object):
|
|||||||
bind_path = name[6:]
|
bind_path = name[6:]
|
||||||
if name.startswith("punix:"):
|
if name.startswith("punix:"):
|
||||||
bind_path = ovs.util.abs_file_name(ovs.dirs.RUNDIR, bind_path)
|
bind_path = ovs.util.abs_file_name(ovs.dirs.RUNDIR, bind_path)
|
||||||
error, sock = ovs.socket_util.make_unix_socket(socket.SOCK_STREAM,
|
error, sock = ovs.socket_util.make_unix_socket(socket.SOCK_STREAM,
|
||||||
True, bind_path, None)
|
True, bind_path,
|
||||||
if error:
|
None)
|
||||||
return error, None
|
if error:
|
||||||
|
return error, None
|
||||||
|
|
||||||
|
elif name.startswith("ptcp:"):
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
remote = name.split(':')
|
||||||
|
sock.bind((remote[1], int(remote[2])))
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception('Unknown connection string')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sock.listen(10)
|
sock.listen(10)
|
||||||
@@ -328,7 +338,10 @@ class PassiveStream(object):
|
|||||||
try:
|
try:
|
||||||
sock, addr = self.socket.accept()
|
sock, addr = self.socket.accept()
|
||||||
ovs.socket_util.set_nonblocking(sock)
|
ovs.socket_util.set_nonblocking(sock)
|
||||||
return 0, Stream(sock, "unix:%s" % addr, 0)
|
if (sock.family == socket.AF_UNIX):
|
||||||
|
return 0, Stream(sock, "unix:%s" % addr, 0)
|
||||||
|
return 0, Stream(sock, 'ptcp:%s:%s' % (addr[0],
|
||||||
|
str(addr[1])), 0)
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
error = ovs.socket_util.get_exception_errno(e)
|
error = ovs.socket_util.get_exception_errno(e)
|
||||||
if error != errno.EAGAIN:
|
if error != errno.EAGAIN:
|
||||||
|
@@ -135,6 +135,35 @@ m4_define([OVSDB_CHECK_IDL],
|
|||||||
OVSDB_CHECK_IDL_TCP_PY($@)
|
OVSDB_CHECK_IDL_TCP_PY($@)
|
||||||
OVSDB_CHECK_IDL_TCP6_PY($@)])
|
OVSDB_CHECK_IDL_TCP6_PY($@)])
|
||||||
|
|
||||||
|
# This test uses the Python IDL implementation with passive tcp
|
||||||
|
m4_define([OVSDB_CHECK_IDL_PASSIVE_TCP_PY],
|
||||||
|
[AT_SETUP([$1 - Python ptcp])
|
||||||
|
AT_SKIP_IF([test $HAVE_PYTHON = no])
|
||||||
|
AT_KEYWORDS([ovsdb server idl positive Python with tcp socket $5])
|
||||||
|
AT_CHECK([ovsdb-tool create db $abs_srcdir/idltest.ovsschema],
|
||||||
|
[0], [stdout], [ignore])
|
||||||
|
# find free TCP port
|
||||||
|
AT_CHECK([ovsdb-server --log-file '-vPATTERN:console:ovsdb-server|%c|%m' --detach --no-chdir --pidfile="`pwd`"/pid --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
|
||||||
|
PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
|
||||||
|
AT_CHECK([kill `cat pid`])
|
||||||
|
|
||||||
|
# start OVSDB server in passive mode
|
||||||
|
AT_CHECK([ovsdb-server --log-file '-vPATTERN:console:ovsdb-server|%c|%m' --detach --no-chdir --pidfile="`pwd`"/pid --remote=punix:socket --remote=tcp:127.0.0.1:$TCP_PORT --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
|
||||||
|
AT_CHECK([$PYTHON $srcdir/test-ovsdb.py -t10 idl_passive $srcdir/idltest.ovsschema ptcp:127.0.0.1:$TCP_PORT $3],
|
||||||
|
[0], [stdout], [ignore], [kill `cat pid`])
|
||||||
|
AT_CHECK([sort stdout | ${PERL} $srcdir/uuidfilt.pl]m4_if([$6],,, [[| $6]]),
|
||||||
|
[0], [$4], [], [kill `cat pid`])
|
||||||
|
AT_CLEANUP
|
||||||
|
])
|
||||||
|
|
||||||
|
OVSDB_CHECK_IDL_PASSIVE_TCP_PY([simple passive idl, initially empty, select empty],
|
||||||
|
[],
|
||||||
|
[['["idltest",{"op":"select","table":"link1","where":[]}]']],
|
||||||
|
[[000: empty
|
||||||
|
001: {"error":null,"result":[{"rows":[]}]}
|
||||||
|
002: done
|
||||||
|
]])
|
||||||
|
|
||||||
OVSDB_CHECK_IDL([simple idl, initially empty, no ops],
|
OVSDB_CHECK_IDL([simple idl, initially empty, no ops],
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
|
@@ -487,6 +487,51 @@ def do_idl(schema_file, remote, *commands):
|
|||||||
print("%03d: done" % step)
|
print("%03d: done" % step)
|
||||||
|
|
||||||
|
|
||||||
|
def do_idl_passive(schema_file, remote, *commands):
|
||||||
|
symtab = {}
|
||||||
|
step = 0
|
||||||
|
schema_helper = ovs.db.idl.SchemaHelper(schema_file)
|
||||||
|
schema_helper.register_all()
|
||||||
|
idl = ovs.db.idl.Idl(remote, schema_helper)
|
||||||
|
|
||||||
|
while idl._session.rpc is None:
|
||||||
|
idl.run()
|
||||||
|
|
||||||
|
rpc = idl._session.rpc
|
||||||
|
|
||||||
|
print_idl(idl, step)
|
||||||
|
step += 1
|
||||||
|
|
||||||
|
for command in commands:
|
||||||
|
json = ovs.json.from_string(command)
|
||||||
|
if isinstance(json, six.string_types):
|
||||||
|
sys.stderr.write("\"%s\": %s\n" % (command, json))
|
||||||
|
sys.exit(1)
|
||||||
|
json = substitute_uuids(json, symtab)
|
||||||
|
request = ovs.jsonrpc.Message.create_request("transact", json)
|
||||||
|
error, reply = rpc.transact_block(request)
|
||||||
|
if error:
|
||||||
|
sys.stderr.write("jsonrpc transaction failed: %s"
|
||||||
|
% os.strerror(error))
|
||||||
|
sys.exit(1)
|
||||||
|
elif reply.error is not None:
|
||||||
|
sys.stderr.write("jsonrpc transaction failed: %s"
|
||||||
|
% reply.error)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
sys.stdout.write("%03d: " % step)
|
||||||
|
sys.stdout.flush()
|
||||||
|
step += 1
|
||||||
|
if reply.result is not None:
|
||||||
|
parse_uuids(reply.result, symtab)
|
||||||
|
reply.id = None
|
||||||
|
sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
idl.close()
|
||||||
|
print("%03d: done" % step)
|
||||||
|
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print("""\
|
print("""\
|
||||||
%(program_name)s: test utility for Open vSwitch database Python bindings
|
%(program_name)s: test utility for Open vSwitch database Python bindings
|
||||||
@@ -587,7 +632,8 @@ def main(argv):
|
|||||||
"parse-column": (do_parse_column, 2),
|
"parse-column": (do_parse_column, 2),
|
||||||
"parse-table": (do_parse_table, (2, 3)),
|
"parse-table": (do_parse_table, (2, 3)),
|
||||||
"parse-schema": (do_parse_schema, 1),
|
"parse-schema": (do_parse_schema, 1),
|
||||||
"idl": (do_idl, (2,))}
|
"idl": (do_idl, (2,)),
|
||||||
|
"idl_passive": (do_idl_passive, (2,))}
|
||||||
|
|
||||||
command_name = args[0]
|
command_name = args[0]
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
|
Reference in New Issue
Block a user