this methods parses host in touple hostname,port. Created to avoid code duplication when support for hostlist in interactive mode will be released.
Signed-off-by: Jiri Prochazka jprochaz@redhat.com --- lnst/Controller/Wizard.py | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-)
diff --git a/lnst/Controller/Wizard.py b/lnst/Controller/Wizard.py index 562efe1..a917949 100644 --- a/lnst/Controller/Wizard.py +++ b/lnst/Controller/Wizard.py @@ -96,24 +96,9 @@ class Wizard:
for host in hostlist: print("Processing host '%s'" % host) - # Check if port was entered along with hostname - if host.find(":") != -1: - hostname = host.split(":")[0] - if hostname == "": - msg = "'%s' does not contain valid hostname\n" % host - sys.stderr.write(msg) - sys.stderr.write("Skipping host '%s'\n" % host) - continue - try: - port = int(host.split(":")[1]) - except: - port = DefaultRPCPort - msg = "Invalid port entered, "\ - "using '%s' instead\n" % port - sys.stderr.write(msg) - else: - hostname = host - port = DefaultRPCPort + hostname, port = self._parse_host(host) + if hostname == -1: + continue
if not self._check_hostname(hostname): sys.stderr.write("Hostname '%s' is not translatable into a " @@ -353,6 +338,31 @@ class Wizard: if data["type"] == "result": return data["result"]
+ def _parse_host(self, host): + """ Parses hostname:port string + @param host String where hostname and optionally port is stored + @return touple with string hostname and int port + """ + if host.find(":") != -1: + hostname = host.split(":")[0] + if hostname == "": + msg = "'%s' does not contain valid hostname\n" % host + sys.stderr.write(msg) + sys.stderr.write("Skipping host '%s'\n" % host) + return -1, -1 + try: + port = int(host.split(":")[1]) + except: + port = DefaultRPCPort + msg = "Invalid port entered, "\ + "using '%s' instead\n" % port + sys.stderr.write(msg) + else: + hostname = host + port = DefaultRPCPort + + return hostname, port + def _query_continuation(self): """ Queries user for adding next machine @return True if user wants to add another machine, False otherwise
user will be able to enter hostlist in interactive mode, so he doesn't have to manually enter hostnames and can only choose which interfaces he wants to add in slave machine XML.
Signed-off-by: Jiri Prochazka jprochaz@redhat.com --- lnst-pool-wizard | 11 ++++++----- lnst/Controller/Wizard.py | 29 +++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/lnst-pool-wizard b/lnst-pool-wizard index a2f1275..8313e74 100755 --- a/lnst-pool-wizard +++ b/lnst-pool-wizard @@ -26,12 +26,12 @@ def help(retval=0): " -h, --help display this help text and exit\n"\ " -p, --pool_dir <directory> set the pool dir (works both in) "\ "interactive and noninteractive mode\n"\ - " -i, --interactive start wizard in interactive mode (this "\ - "is default mode)\n"\ + " -i, --interactive start wizard in interactive mode (default)"\ " -n, --noninteractive start wizard in noninteractive mode\n"\ " -v, --virtual start wizard in mode for VMs\n"\ "Examples:\n"\ " lnst-pool-wizard --interactive\n"\ + " lnst-pool-wizard hostname1:1234 hostname2\n"\ " lnst-pool-wizard --noninteractive 192.168.122.2\n"\ " lnst-pool-wizard -n 192.168.122.2:8888 192.168.122.4\n"\ " lnst-pool-wizard -p ".pool/" -n 192.168.1.1:8877 192.168.122.4" @@ -61,8 +61,6 @@ def main(): if not args: sys.stderr.write("No hostnames entered\n") return RETVAL_ERR - else: - hostlist = args mode = "noninteractive" elif opt in ("-v", "--virtual"): mode = "virtual" @@ -74,6 +72,9 @@ def main(): else: help(RETVAL_ERR)
+ if args is not None: + hostlist = args + wizard = Wizard()
if mode == "noninteractive": @@ -81,7 +82,7 @@ def main(): elif mode == "virtual": wizard.virtual(pool_dir) else: - wizard.interactive(pool_dir) + wizard.interactive(hostlist, pool_dir)
sys.exit(RETVAL_PASS)
diff --git a/lnst/Controller/Wizard.py b/lnst/Controller/Wizard.py index a917949..2f99a25 100644 --- a/lnst/Controller/Wizard.py +++ b/lnst/Controller/Wizard.py @@ -32,13 +32,37 @@ PATH_NOT_DIR = 3
class Wizard: - - def interactive(self, pool_dir=None): + def interactive(self, hostlist=None, pool_dir=None): """ Starts Wizard in an interactive mode @param pool_dir Path to pool directory (optional) """ pool_dir = self._check_and_query_pool_dir(pool_dir)
+ if hostlist is not None: + for host in hostlist: + hostname, port = self._parse_host(host) + if hostname == -1: + continue + + sock = self._get_connection(hostname, port) + + if sock is None: + continue + machine_interfaces = self._get_machine_interfaces(sock) + sock.close() + + if machine_interfaces == {}: + sys.stderr.write("No suitable interfaces found on the host " + "'%s:%s'\n" % (hostname, port)) + elif machine_interfaces is not None: + filename = self._query_filename(hostname) + self._create_xml(machine_interfaces=machine_interfaces, + hostname=hostname, pool_dir=pool_dir, + filename=filename, port=port, + mode="interactive") + + return + while True: hostname = self._query_hostname() port = self._query_port() @@ -62,6 +86,7 @@ class Wizard: hostname=hostname, pool_dir=pool_dir, filename=filename, port=port, mode="interactive") + if self._query_continuation(): continue else:
Fri, Dec 11, 2015 at 03:19:24PM CET, jprochaz@redhat.com wrote:
user will be able to enter hostlist in interactive mode, so he doesn't have to manually enter hostnames and can only choose which interfaces he wants to add in slave machine XML.
Signed-off-by: Jiri Prochazka jprochaz@redhat.com
lnst-pool-wizard | 11 ++++++----- lnst/Controller/Wizard.py | 29 +++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/lnst-pool-wizard b/lnst-pool-wizard index a2f1275..8313e74 100755 --- a/lnst-pool-wizard +++ b/lnst-pool-wizard @@ -26,12 +26,12 @@ def help(retval=0): " -h, --help display this help text and exit\n"\ " -p, --pool_dir <directory> set the pool dir (works both in) "\ "interactive and noninteractive mode\n"\
" -i, --interactive start wizard in interactive mode (this "\
"is default mode)\n"\
" -i, --interactive start wizard in interactive mode (default)"\ " -n, --noninteractive start wizard in noninteractive mode\n"\ " -v, --virtual start wizard in mode for VMs\n"\ "Examples:\n"\ " lnst-pool-wizard --interactive\n"\
" lnst-pool-wizard hostname1:1234 hostname2\n"\ " lnst-pool-wizard --noninteractive 192.168.122.2\n"\ " lnst-pool-wizard -n 192.168.122.2:8888 192.168.122.4\n"\ " lnst-pool-wizard -p \".pool/\" -n 192.168.1.1:8877 192.168.122.4"
@@ -61,8 +61,6 @@ def main(): if not args: sys.stderr.write("No hostnames entered\n") return RETVAL_ERR
else:
hostlist = args mode = "noninteractive" elif opt in ("-v", "--virtual"): mode = "virtual"
@@ -74,6 +72,9 @@ def main(): else: help(RETVAL_ERR)
- if args is not None:
This condition is incorrect. args is ALWAYS list [], either empty or non-empty, therefore check for None is wrong.
This commit actually broke interactive mode if no machines are specified on command line, in that case it would go through empty hostlist and return without prompting for anything.
I already sent a fix for this.
-Jan
hostlist = args
wizard = Wizard()
if mode == "noninteractive":
@@ -81,7 +82,7 @@ def main(): elif mode == "virtual": wizard.virtual(pool_dir) else:
wizard.interactive(pool_dir)
wizard.interactive(hostlist, pool_dir)
sys.exit(RETVAL_PASS)
diff --git a/lnst/Controller/Wizard.py b/lnst/Controller/Wizard.py index a917949..2f99a25 100644 --- a/lnst/Controller/Wizard.py +++ b/lnst/Controller/Wizard.py @@ -32,13 +32,37 @@ PATH_NOT_DIR = 3
class Wizard:
- def interactive(self, pool_dir=None):
def interactive(self, hostlist=None, pool_dir=None): """ Starts Wizard in an interactive mode @param pool_dir Path to pool directory (optional) """ pool_dir = self._check_and_query_pool_dir(pool_dir)
if hostlist is not None:
for host in hostlist:
hostname, port = self._parse_host(host)
if hostname == -1:
continue
sock = self._get_connection(hostname, port)
if sock is None:
continue
machine_interfaces = self._get_machine_interfaces(sock)
sock.close()
if machine_interfaces == {}:
sys.stderr.write("No suitable interfaces found on the host "
"'%s:%s'\n" % (hostname, port))
elif machine_interfaces is not None:
filename = self._query_filename(hostname)
self._create_xml(machine_interfaces=machine_interfaces,
hostname=hostname, pool_dir=pool_dir,
filename=filename, port=port,
mode="interactive")
return
while True: hostname = self._query_hostname() port = self._query_port()
@@ -62,6 +86,7 @@ class Wizard: hostname=hostname, pool_dir=pool_dir, filename=filename, port=port, mode="interactive")
if self._query_continuation(): continue else:
-- 2.4.3 _______________________________________________ LNST-developers mailing list lnst-developers@lists.fedorahosted.org https://lists.fedorahosted.org/admin/lists/lnst-developers@lists.fedorahoste...
also updates setup.py
Signed-off-by: Jiri Prochazka jprochaz@redhat.com --- install/lnst-pool-wizard.bash | 36 ++++++++++++++++++++++++++++++++++++ setup.py | 3 ++- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 install/lnst-pool-wizard.bash
diff --git a/install/lnst-pool-wizard.bash b/install/lnst-pool-wizard.bash new file mode 100644 index 0000000..599b6fa --- /dev/null +++ b/install/lnst-pool-wizard.bash @@ -0,0 +1,36 @@ +#!/bin/bash + +# Bash completion script for lnst-pool-wizard command +# Author: Jiri Prochazka jprochaz@redhat.com + +_lnst_pool_wizard() +{ + local SHORT_OPTS="-h -i -n -v" + local LONG_OPTS="--help --interactive --noninteractive --virtual" + local REQUIRE_ARG="-p --pool_dir" + + local cur=${COMP_WORDS[COMP_CWORD]} + local prev=${COMP_WORDS[COMP_CWORD-1]} + + case "$prev" in + -p|--pool_dir) + _filedir + return 0 + ;; + esac + + # Complete long and shor options + if [[ "$cur" == --* ]]; then + COMPREPLY=( $(compgen -W "$LONG_OPTS" -- $cur) ) + [ ${#COMPREPLY[@]} = 1 ] && COMPREPLY=$(printf %q%s "$COMPREPLY" " ") + return 0 + elif [[ "$cur" == -* ]]; then + COMPREPLY=( $(compgen -W "$SHORT_OPTS" -- $cur) ) + [ ${#COMPREPLY[@]} = 1 ] && COMPREPLY=$(printf %q%s "$COMPREPLY" " ") + return 0 + fi + + return 0 +} + +complete -o nospace -F _lnst_pool_wizard lnst-pool-wizard diff --git a/setup.py b/setup.py index 628ac1f..9eac0c9 100755 --- a/setup.py +++ b/setup.py @@ -165,7 +165,8 @@ MAN_PAGES = [(MAN_DIR, ["install/lnst-ctl.1.gz", "install/lnst-slave.1.gz"])] CONFIG = [(CONF_DIR, ["install/lnst-ctl.conf", "install/lnst-slave.conf"])]
BASH_COMP = [(BASH_COMP_DIR, ["install/lnst-ctl.bash", - "install/lnst-slave.bash"])] + "install/lnst-slave.bash", + "install/lnst-pool-wizard.bash"])]
SCHEMAS = [(CTL_RESOURCE_DIR, ["schema-recipe.rng", "schema-sm.rng"])]
adds man page for pool wizard in install/ directory and updates setup.py file
Signed-off-by: Jiri Prochazka jprochaz@redhat.com --- install/lnst-pool-wizard.1.in | 76 +++++++++++++++++++++++++++++++++++++++++++ setup.py | 7 ++-- 2 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 install/lnst-pool-wizard.1.in
diff --git a/install/lnst-pool-wizard.1.in b/install/lnst-pool-wizard.1.in new file mode 100644 index 0000000..6616dca --- /dev/null +++ b/install/lnst-pool-wizard.1.in @@ -0,0 +1,76 @@ +.TH LNST-POOL-WIZARD "1" "@date@" + +." To view this file while editing, run it through groff: +." groff -Tascii -man lnst-pool-wizard.1 | less -r + +." This file is a template that contains placeholders for +." certain values. It needs to be processed before it can +." be used as a man-page. + +.SH NAME +lnst-pool-wizard - Linux Network Stack Test Pool Wizard +.SH SYNOPSIS +.BR +.B lnst-pool-wizard +[\fB-h\fR] [\fIMODE\fR] [\fB-p \fIpool_dir\fR] [\fIHOSTNAME[:PORT]\fR...] +.SH DESCRIPTION +Linux Network Stack Test is a tool that supports development and execution +of automated and portable network tests. For detailed description of the +architecture of LNST please refer to project website +(link listed on +.B INTERNET RESOURCES +bellow). + +.B lnst-pool-wizard +is a script that runs wizard for creating slave machine description XML files +.SH MODES +.TP +.B -i, --interactive +If any hostnames are specified, wizard will try to connect to them, get +available interfaces and ask user which of the interfaces should be added +to the result description XML file. If no hostname is specified, wizard +will ask for hostname via prompt. +.TP +.B -n, --noninteractive +Wizard will try to connect to all hostnames specified in arguments and for +each one create XML file with all available interfaces. +.TP +.B -v, --virtual +This mode is for virtual hosts created by libvirt. Wizard queries user +for libvirt domain and tries to retrieve IP address from DHCP Leases. +This IP address will be used as hostname in Slave Description XML file. +.SH OPTIONS +.TP +.B -h, --help +Display usage of this command. +.TP +.BI "-p, --pool_dir=" directory +Directory where result XML files will be stored. If none is entered +default location will be used (~/.lnst/pool) +.SH INTERNET RESOURCES +Project Homepage: http://lnst-project.org/ +.br +Online Documentation: https://github.com/jpirko/lnst/wiki#learn +.br +Git Source Tree: https://github.com/jpirko/lnst +.br +Mailing List: lnst-developers@lists.fedorahosted.org + +.SH AUTHORS +\fBJiri Pirko\fR jiri@resnulli.us +.br +\fBJan Tluka\fR jtluka@redhat.com +.br +\fBOndrej Lichtner\fR olichtne@redhat.com +.br +\fBJiri Prochazka\fR jprochaz@redhat.com +.br +\fBJiri Zupka\fR jzupka@redhat.com +.br +\fBRadek Pazdera\fR radek@pazdera.co.uk +.SH COPYRIGHT +Copyright (C) 2011-2015 Red Hat, Inc. + +LNST is distributed under GNU General Public License version 2. See +the file "COPYING" in the source distribution for information on terms & +conditions for accessing and otherwise using LNST. diff --git a/setup.py b/setup.py index 9eac0c9..6a269ea 100755 --- a/setup.py +++ b/setup.py @@ -79,7 +79,8 @@ TEMPLATES = [ "install/lnst-ctl.conf.in", "install/lnst-slave.conf.in", "install/lnst-ctl.1.in", -"install/lnst-slave.1.in" +"install/lnst-slave.1.in", +"install/lnst-pool-wizard.1.in" ]
for template in TEMPLATES: @@ -89,6 +90,7 @@ for template in TEMPLATES: # Pack man pages gzip_file("install/lnst-ctl.1") gzip_file("install/lnst-slave.1") +gzip_file("install/lnst-pool-wizard.1") # ---
@@ -160,7 +162,8 @@ MULTICAST_TEST_TOOLS = [ "test_tools/tcp_conn/tcp_listen.c"]) ]
-MAN_PAGES = [(MAN_DIR, ["install/lnst-ctl.1.gz", "install/lnst-slave.1.gz"])] +MAN_PAGES = [(MAN_DIR, ["install/lnst-ctl.1.gz", "install/lnst-slave.1.gz", + "install/lnst-pool-wizard.1.gz"])]
CONFIG = [(CONF_DIR, ["install/lnst-ctl.conf", "install/lnst-slave.conf"])]
On Fri, Dec 11, 2015 at 03:19:23PM +0100, Jiri Prochazka wrote:
this methods parses host in touple hostname,port. Created to avoid code duplication when support for hostlist in interactive mode will be released.
Signed-off-by: Jiri Prochazka jprochaz@redhat.com
Acked-by: Ondrej Lichtner olichtne@redhat.com
lnst-developers@lists.fedorahosted.org