Merge "XenAPI: add support for conntrack with XenServer"
This commit is contained in:
commit
e08e06fa22
|
@ -29,7 +29,6 @@ from oslo_serialization import jsonutils as json
|
||||||
import os
|
import os
|
||||||
import select
|
import select
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
|
||||||
|
|
||||||
import XenAPI
|
import XenAPI
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ def parse_args():
|
||||||
exec_name = sys.argv.pop(0)
|
exec_name = sys.argv.pop(0)
|
||||||
# argv[0] required; path to conf file
|
# argv[0] required; path to conf file
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
print("%s: No command specified" % exec_name)
|
sys.stderr.write("%s: No command specified" % exec_name)
|
||||||
sys.exit(RC_NOCOMMAND)
|
sys.exit(RC_NOCOMMAND)
|
||||||
|
|
||||||
config_file = sys.argv.pop(0)
|
config_file = sys.argv.pop(0)
|
||||||
|
@ -59,7 +58,7 @@ def _xenapi_section_name(config):
|
||||||
if len(sections) == 1:
|
if len(sections) == 1:
|
||||||
return sections[0]
|
return sections[0]
|
||||||
|
|
||||||
print("Multiple [xenapi] sections or no [xenapi] section found!")
|
sys.stderr.write("Multiple [xenapi] sections or no [xenapi] section found!")
|
||||||
sys.exit(RC_BADCONFIG)
|
sys.exit(RC_BADCONFIG)
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,13 +73,14 @@ def load_configuration(exec_name, config_file):
|
||||||
username = config.get(section, "xenapi_connection_username")
|
username = config.get(section, "xenapi_connection_username")
|
||||||
password = config.get(section, "xenapi_connection_password")
|
password = config.get(section, "xenapi_connection_password")
|
||||||
except ConfigParser.Error:
|
except ConfigParser.Error:
|
||||||
print("%s: Incorrect configuration file: %s" % (exec_name, config_file))
|
sys.stderr.write("%s: Incorrect configuration file: %s" %
|
||||||
|
(exec_name, config_file))
|
||||||
sys.exit(RC_BADCONFIG)
|
sys.exit(RC_BADCONFIG)
|
||||||
if not url or not password:
|
if not url or not password:
|
||||||
msg = ("%s: Must specify xenapi_connection_url, "
|
msg = ("%s: Must specify xenapi_connection_url, "
|
||||||
"xenapi_connection_username (optionally), and "
|
"xenapi_connection_username (optionally), and "
|
||||||
"xenapi_connection_password in %s") % (exec_name, config_file)
|
"xenapi_connection_password in %s") % (exec_name, config_file)
|
||||||
print(msg)
|
sys.stderr.write(msg)
|
||||||
sys.exit(RC_BADCONFIG)
|
sys.exit(RC_BADCONFIG)
|
||||||
return dict(
|
return dict(
|
||||||
filters_path=filters_path,
|
filters_path=filters_path,
|
||||||
|
@ -105,7 +105,7 @@ def filter_command(exec_name, filters_path, user_args, exec_dirs):
|
||||||
filter_match = wrapper.match_filter(
|
filter_match = wrapper.match_filter(
|
||||||
filters, user_args, exec_dirs=exec_dirs)
|
filters, user_args, exec_dirs=exec_dirs)
|
||||||
if not filter_match:
|
if not filter_match:
|
||||||
print("Unauthorized command: %s" % ' '.join(user_args))
|
sys.stderr.write("Unauthorized command: %s" % ' '.join(user_args))
|
||||||
sys.exit(RC_UNAUTHORIZED)
|
sys.exit(RC_UNAUTHORIZED)
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,11 +118,17 @@ def run_command(url, username, password, user_args, cmd_input):
|
||||||
result = session.xenapi.host.call_plugin(
|
result = session.xenapi.host.call_plugin(
|
||||||
host, 'netwrap', 'run_command',
|
host, 'netwrap', 'run_command',
|
||||||
{'cmd': json.dumps(user_args), 'cmd_input': json.dumps(cmd_input)})
|
{'cmd': json.dumps(user_args), 'cmd_input': json.dumps(cmd_input)})
|
||||||
return json.loads(result)
|
result_dict = json.loads(result)
|
||||||
|
returncode = result_dict.get('returncode')
|
||||||
|
captured_stdout = result_dict.get('out')
|
||||||
|
captured_stderr = result_dict.get('err')
|
||||||
|
sys.stdout.write(captured_stdout)
|
||||||
|
sys.stderr.write(captured_stderr)
|
||||||
|
sys.exit(returncode)
|
||||||
finally:
|
finally:
|
||||||
session.xenapi.session.logout()
|
session.xenapi.session.logout()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
sys.stderr.write("Failed to execute command in Dom0, %s" % e)
|
||||||
sys.exit(RC_XENAPI_ERROR)
|
sys.exit(RC_XENAPI_ERROR)
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,4 +148,4 @@ def main():
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(main())
|
main()
|
||||||
|
|
|
@ -44,6 +44,7 @@ ALLOWED_CMDS = [
|
||||||
'ovs-ofctl',
|
'ovs-ofctl',
|
||||||
'ovs-vsctl',
|
'ovs-vsctl',
|
||||||
'ovsdb-client',
|
'ovsdb-client',
|
||||||
|
'conntrack',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,10 +62,7 @@ def _run_command(cmd, cmd_input):
|
||||||
proc = subprocess.Popen(cmd, shell=False, stdin=pipe, stdout=pipe,
|
proc = subprocess.Popen(cmd, shell=False, stdin=pipe, stdout=pipe,
|
||||||
stderr=pipe, close_fds=True)
|
stderr=pipe, close_fds=True)
|
||||||
(out, err) = proc.communicate(cmd_input)
|
(out, err) = proc.communicate(cmd_input)
|
||||||
|
return proc.returncode, out, err
|
||||||
if proc.returncode != 0:
|
|
||||||
raise PluginError(err)
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
def run_command(session, args):
|
def run_command(session, args):
|
||||||
|
@ -72,7 +70,16 @@ def run_command(session, args):
|
||||||
if cmd and cmd[0] not in ALLOWED_CMDS:
|
if cmd and cmd[0] not in ALLOWED_CMDS:
|
||||||
msg = _("Dom0 execution of '%s' is not permitted") % cmd[0]
|
msg = _("Dom0 execution of '%s' is not permitted") % cmd[0]
|
||||||
raise PluginError(msg)
|
raise PluginError(msg)
|
||||||
result = _run_command(cmd, json.loads(args.get('cmd_input', 'null')))
|
returncode, out, err = _run_command(
|
||||||
|
cmd, json.loads(args.get('cmd_input', 'null')))
|
||||||
|
if not err:
|
||||||
|
err = ""
|
||||||
|
if not out:
|
||||||
|
out = ""
|
||||||
|
# This runs in Dom0, will return to neutron-ovs-agent in compute node
|
||||||
|
result = {'returncode': returncode,
|
||||||
|
'out': out,
|
||||||
|
'err': err}
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue