Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2017-01-23 11:39:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2017-01-10 10:43:59.527039189 +0100 +++ /work/SRC/openSUSE:Factory/.crmsh.new/crmsh.changes 2017-01-23 11:39:07.811068754 +0100 @@ -1,0 +2,11 @@ +Wed Jan 04 15:29:45 UTC 2017 - [email protected] + +- Update to version 2.3.2+git.1483543612.cf853f8: + * medium: ui_cluster: Fix broken cluster remove command + * medium: bootstrap: Invoke _remote commands correctly + * low: ui_cluster: No need to check the cluster stack in requires + * low: bootstrap: Avoid warning if known_hosts doesn't exist + * low: bootstrap: Handle None as result from remote command correctly + * low: bootstrap: Don't check for ptty for _remote stages + +------------------------------------------------------------------- Old: ---- crmsh-2.3.2+git.1481875498.8cd1dd9.tar.bz2 New: ---- crmsh-2.3.2+git.1483543612.cf853f8.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.9ZclhS/_old 2017-01-23 11:39:08.358991042 +0100 +++ /var/tmp/diff_new_pack.9ZclhS/_new 2017-01-23 11:39:08.358991042 +0100 @@ -1,7 +1,7 @@ # # spec file for package crmsh # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -38,7 +38,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0+ Group: %{pkg_group} -Version: 2.3.2+git.1481875498.8cd1dd9 +Version: 2.3.2+git.1483543612.cf853f8 Release: 0 Url: http://crmsh.github.io Source0: %{name}-%{version}.tar.bz2 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.9ZclhS/_old 2017-01-23 11:39:08.406984235 +0100 +++ /var/tmp/diff_new_pack.9ZclhS/_new 2017-01-23 11:39:08.406984235 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/ClusterLabs/crmsh.git</param> - <param name="changesrevision">8cd1dd93177cde41701277ca8804c2ebbd3f2d4a</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">cf853f84636ccf8432b1cba6c64c4b782dcd3e90</param></service></servicedata> \ No newline at end of file ++++++ crmsh-2.3.2+git.1481875498.8cd1dd9.tar.bz2 -> crmsh-2.3.2+git.1483543612.cf853f8.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-2.3.2+git.1481875498.8cd1dd9/crmsh/bootstrap.py new/crmsh-2.3.2+git.1483543612.cf853f8/crmsh/bootstrap.py --- old/crmsh-2.3.2+git.1481875498.8cd1dd9/crmsh/bootstrap.py 2016-12-16 09:04:58.000000000 +0100 +++ new/crmsh-2.3.2+git.1483543612.cf853f8/crmsh/bootstrap.py 2017-01-04 16:26:52.000000000 +0100 @@ -600,7 +600,7 @@ invoke("csync2 -rxv %s" % (path)) -def init_csync2_remote(newhost): +def init_csync2_remote(): """ It would be nice if we could just have csync2.cfg include a directory, which in turn included one file per node which would be referenced via @@ -612,6 +612,7 @@ remote node to csync2 config on some existing node. It is intentionally not documented in ha-cluster-init's user-visible usage information. """ + newhost = _context.cluster_node if not newhost: error("Hostname not specified") @@ -1168,13 +1169,14 @@ # checking) ensures that at least *this* host has every other host in its # known_hosts known_hosts_new = set() - log("parallax.call {} : {}".format(hosts, "cat /root/.ssh/known_hosts")) - results = parallax.call(hosts, "cat /root/.ssh/known_hosts", opts) + cat_cmd = "[ -e /root/.ssh/known_hosts ] && cat /root/.ssh/known_hosts || true" + log("parallax.call {} : {}".format(hosts, cat_cmd)) + results = parallax.call(hosts, cat_cmd, opts) for host, result in results.iteritems(): if isinstance(result, parallax.Error): warn("Failed to get known_hosts from {}: {}".format(host, str(result))) else: - known_hosts_new.update(result[1].splitlines()) + known_hosts_new.update((result[1] or "").splitlines()) if known_hosts_new: hoststxt = "\n".join(sorted(known_hosts_new)) tmpf = utils.str2tmp(hoststxt) @@ -1382,7 +1384,7 @@ def bootstrap_init(cluster_name="hacluster", nic=None, ocfs2_device=None, shared_device=None, sbd_device=None, quiet=False, template=None, admin_ip=None, yes_to_all=False, - unicast=False, watchdog=None, stage=None): + unicast=False, watchdog=None, stage=None, args=None): """ -i <nic> -o <ocfs2-device> @@ -1435,14 +1437,20 @@ error("Cluster is currently active - can't run %s stage" % (stage)) # Need hostname resolution to work, want NTP (but don't block ssh_remote or csync2_remote) - check_tty() - if not check_prereqs(stage): - return + if stage not in ('ssh_remote', 'csync2_remote'): + check_tty() + if not check_prereqs(stage): + return + elif stage == 'csync2_remote': + log("args: {}".format(args)) + if len(args) != 2: + error("Expected NODE argument to csync2_remote") + _context.cluster_node = args[1] init() if stage != "": - locals()["init_" + stage]() + globals()["init_" + stage]() else: if watchdog is not None: init_watchdog() @@ -1491,7 +1499,7 @@ init() if stage != "": - locals()["join_" + stage](cluster_node) + globals()["join_" + stage](cluster_node) else: if not yes_to_all and cluster_node is None: status("""Join This Node to Cluster: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-2.3.2+git.1481875498.8cd1dd9/crmsh/term.py new/crmsh-2.3.2+git.1483543612.cf853f8/crmsh/term.py --- old/crmsh-2.3.2+git.1481875498.8cd1dd9/crmsh/term.py 2016-12-16 09:04:58.000000000 +0100 +++ new/crmsh-2.3.2+git.1483543612.cf853f8/crmsh/term.py 2017-01-04 16:26:52.000000000 +0100 @@ -72,57 +72,35 @@ _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split() -def init(): - """ - Initialize attributes with appropriate values for the current terminal. +def _tigetstr(cap_name): + import curses + cap = curses.tigetstr(cap_name) or '' + + # String capabilities can include "delays" of the form "$<2>". + # For any modern terminal, we should be able to just ignore + # these, so strip them out. + # terminof(5) states that: + # A "/" suffix indicates that the padding is mandatory and forces a + # delay of the given number of milliseconds even on devices for which + # xon is present to indicate flow control. + # So let's respect that. But not the optional ones. + cap = re.sub(r'\$<\d+>[*]?', '', cap) + + # To switch back to "NORMAL", we use sgr0, which resets "everything" to defaults. + # That on some terminals includes ending "alternate character set mode". + # Which is usually done by appending '\017'. Unfortunately, less -R + # does not eat that, but shows it as an annoying inverse '^O' + # Instead of falling back to less -r, which would have other implications as well, + # strip off that '\017': we don't use the alternative character set, + # so we won't need to reset it either. + if cap_name == 'sgr0': + cap = re.sub(r'\017$', '', cap) - `_term_stream` is the stream that will be used for terminal - output; if this stream is not a tty, then the terminal is - assumed to be a dumb terminal (i.e., have no capabilities). - """ - def _tigetstr(cap_name): - import curses - cap = curses.tigetstr(cap_name) or '' + return cap - # String capabilities can include "delays" of the form "$<2>". - # For any modern terminal, we should be able to just ignore - # these, so strip them out. - # terminof(5) states that: - # A "/" suffix indicates that the padding is mandatory and forces a - # delay of the given number of milliseconds even on devices for which - # xon is present to indicate flow control. - # So let's respect that. But not the optional ones. - cap = re.sub(r'\$<\d+>[*]?', '', cap) - - # To switch back to "NORMAL", we use sgr0, which resets "everything" to defaults. - # That on some terminals includes ending "alternate character set mode". - # Which is usually done by appending '\017'. Unfortunately, less -R - # does not eat that, but shows it as an annoying inverse '^O' - # Instead of falling back to less -r, which would have other implications as well, - # strip off that '\017': we don't use the alternative character set, - # so we won't need to reset it either. - if cap_name == 'sgr0': - cap = re.sub(r'\017$', '', cap) - return cap - - _term_stream = sys.stdout - # Curses isn't available on all platforms - try: - import curses - except: - sys.stderr.write("INFO: no curses support: you won't see colors\n") - return - # If the stream isn't a tty, then assume it has no capabilities. - from . import config - if not _term_stream.isatty() and 'color-always' not in config.color.style: - return - # Check the terminal type. If we fail, then assume that the - # terminal has no capabilities. - try: - curses.setupterm() - except: - return +def _lookup_caps(): + import curses # Look up numeric capabilities. colors.COLS = curses.tigetnum('cols') @@ -150,6 +128,35 @@ setattr(colors, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '') +def init(): + """ + Initialize attributes with appropriate values for the current terminal. + + `_term_stream` is the stream that will be used for terminal + output; if this stream is not a tty, then the terminal is + assumed to be a dumb terminal (i.e., have no capabilities). + """ + _term_stream = sys.stdout + # Curses isn't available on all platforms + try: + import curses + except ImportError: + sys.stderr.write("INFO: no curses support: you won't see colors\n") + return + # If the stream isn't a tty, then assume it has no capabilities. + from . import config + if not _term_stream.isatty() and 'color-always' not in config.color.style: + return + # Check the terminal type. If we fail, then assume that the + # terminal has no capabilities. + try: + curses.setupterm() + except curses.error: + return + + _lookup_caps() + + def render(template): """ Replace each $-substitutions in the given template string with diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-2.3.2+git.1481875498.8cd1dd9/crmsh/ui_cluster.py new/crmsh-2.3.2+git.1483543612.cf853f8/crmsh/ui_cluster.py --- old/crmsh-2.3.2+git.1481875498.8cd1dd9/crmsh/ui_cluster.py 2016-12-16 09:04:58.000000000 +0100 +++ new/crmsh-2.3.2+git.1483543612.cf853f8/crmsh/ui_cluster.py 2017-01-04 16:26:52.000000000 +0100 @@ -47,9 +47,6 @@ name = "cluster" def requires(self): - stack = utils.cluster_stack() - if len(stack) > 0 and stack != 'corosync': - err_buf.warning("Unsupported cluster stack %s detected." % (stack)) return True def __init__(self): @@ -195,7 +192,8 @@ yes_to_all=options.yes_to_all, unicast=options.unicast, watchdog=options.watchdog, - stage=stage) + stage=stage, + args=args) # if options.geo: # bootstrap.bootstrap_init_geo() @@ -290,8 +288,7 @@ parser.add_option("-y", "--yes", help='Answer "yes" to all prompts (use with caution)', action="store_true", dest="yes_to_all") parser.add_option("-c", "--cluster-node", dest="cluster_node", help="IP address or hostname of cluster node which will be deleted", metavar="HOST") - args = args - options, args = parser.parse_args(args) + options, args = parser.parse_args(list(args)) if options.cluster_node is not None and options.cluster_node not in args: args = list(args) + [options.cluster_node] if len(args) == 0: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-2.3.2+git.1481875498.8cd1dd9/crmsh/ui_utils.py new/crmsh-2.3.2+git.1483543612.cf853f8/crmsh/ui_utils.py --- old/crmsh-2.3.2+git.1481875498.8cd1dd9/crmsh/ui_utils.py 2016-12-16 09:04:58.000000000 +0100 +++ new/crmsh-2.3.2+git.1483543612.cf853f8/crmsh/ui_utils.py 2017-01-04 16:26:52.000000000 +0100 @@ -83,25 +83,24 @@ configure graph [<gtype> [<file> [<img_format>]]] history graph <pe> [<gtype> [<file> [<img_format>]]] ''' + def tryarg(n, orelse): + try: + return args[n] + except IndexError: + return orelse + except TypeError: + return orelse + from .crm_gv import gv_types gtype, outf, ftype = None, None, None - try: - gtype = args[0] - if gtype not in gv_types: - common_err("graph type %s is not supported" % gtype) - return False, gtype, outf, ftype - except: - gtype = "dot" - try: - outf = args[1] - if not utils.is_path_sane(outf): - return False, gtype, outf, ftype - except: - outf = None - try: - ftype = args[2] - except: - ftype = gtype + gtype = tryarg(0, "dot") + if gtype not in gv_types: + common_err("graph type %s is not supported" % gtype) + return False, gtype, outf, ftype + outf = tryarg(1, None) + if outf is not None and not utils.is_path_sane(outf): + return False, gtype, outf, ftype + ftype = tryarg(2, gtype) return True, gtype, outf, ftype
