XenAPI: add support for conntrack with XenServer
With XenServer as hypervisor, the commands neutron-ovs-agent in compute node run are actually executed in Dom0. But current Dom0 plugin doesn't allow conntrack command, this patch is to add such support. Also, the exitcode the commands returned in Dom0 will pass through Dom0 to neutron to make sure the plugin is only aimed executing commands, it doesn't deal with business scenario. Closes-Bug: #1603400 Change-Id: I304788240bcd590ec211bca052fe64594a4e6eca
This commit is contained in:
parent
2be2d97d11
commit
0d8483391d
@ -29,7 +29,6 @@ from oslo_serialization import jsonutils as json
|
||||
import os
|
||||
import select
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import XenAPI
|
||||
|
||||
@ -45,7 +44,7 @@ def parse_args():
|
||||
exec_name = sys.argv.pop(0)
|
||||
# argv[0] required; path to conf file
|
||||
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)
|
||||
|
||||
config_file = sys.argv.pop(0)
|
||||
@ -59,7 +58,7 @@ def _xenapi_section_name(config):
|
||||
if len(sections) == 1:
|
||||
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)
|
||||
|
||||
|
||||
@ -74,13 +73,14 @@ def load_configuration(exec_name, config_file):
|
||||
username = config.get(section, "xenapi_connection_username")
|
||||
password = config.get(section, "xenapi_connection_password")
|
||||
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)
|
||||
if not url or not password:
|
||||
msg = ("%s: Must specify xenapi_connection_url, "
|
||||
"xenapi_connection_username (optionally), and "
|
||||
"xenapi_connection_password in %s") % (exec_name, config_file)
|
||||
print(msg)
|
||||
sys.stderr.write(msg)
|
||||
sys.exit(RC_BADCONFIG)
|
||||
return dict(
|
||||
filters_path=filters_path,
|
||||
@ -105,7 +105,7 @@ def filter_command(exec_name, filters_path, user_args, exec_dirs):
|
||||
filter_match = wrapper.match_filter(
|
||||
filters, user_args, exec_dirs=exec_dirs)
|
||||
if not filter_match:
|
||||
print("Unauthorized command: %s" % ' '.join(user_args))
|
||||
sys.stderr.write("Unauthorized command: %s" % ' '.join(user_args))
|
||||
sys.exit(RC_UNAUTHORIZED)
|
||||
|
||||
|
||||
@ -118,11 +118,17 @@ def run_command(url, username, password, user_args, cmd_input):
|
||||
result = session.xenapi.host.call_plugin(
|
||||
host, 'netwrap', 'run_command',
|
||||
{'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:
|
||||
session.xenapi.session.logout()
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
sys.stderr.write("Failed to execute command in Dom0, %s" % e)
|
||||
sys.exit(RC_XENAPI_ERROR)
|
||||
|
||||
|
||||
@ -142,4 +148,4 @@ def main():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(main())
|
||||
main()
|
||||
|
@ -44,6 +44,7 @@ ALLOWED_CMDS = [
|
||||
'ovs-ofctl',
|
||||
'ovs-vsctl',
|
||||
'ovsdb-client',
|
||||
'conntrack',
|
||||
]
|
||||
|
||||
|
||||
@ -61,10 +62,7 @@ def _run_command(cmd, cmd_input):
|
||||
proc = subprocess.Popen(cmd, shell=False, stdin=pipe, stdout=pipe,
|
||||
stderr=pipe, close_fds=True)
|
||||
(out, err) = proc.communicate(cmd_input)
|
||||
|
||||
if proc.returncode != 0:
|
||||
raise PluginError(err)
|
||||
return out
|
||||
return proc.returncode, out, err
|
||||
|
||||
|
||||
def run_command(session, args):
|
||||
@ -72,7 +70,16 @@ def run_command(session, args):
|
||||
if cmd and cmd[0] not in ALLOWED_CMDS:
|
||||
msg = _("Dom0 execution of '%s' is not permitted") % cmd[0]
|
||||
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)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user