Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2017-11-27 22:19:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Mon Nov 27 22:19:07 2017 rev:133 rq:546044 version:4.0.0+git.1511604050.816cb0f5 Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2017-11-13 14:07:55.349858835 +0100 +++ /work/SRC/openSUSE:Factory/.crmsh.new/crmsh.changes 2017-11-27 22:19:08.717035955 +0100 @@ -1,0 +2,21 @@ +Mon Nov 27 15:06:41 UTC 2017 - kgronl...@suse.com + +- Update to version 4.0.0+git.1511604050.816cb0f5: + * high: crm_rpmcheck: Fix bytes to str encoding error (bsc#1069294) + * medium: bootstrap: Missing dmidecode on ppc64le (bsc#1069802) + +------------------------------------------------------------------- +Tue Nov 21 09:51:15 UTC 2017 - kgronl...@suse.com + +- Update to version 4.0.0+git.1511256861.18b44cfa: + * high: bootstrap: Use default IP address for ring0 (bsc#1069142) + * medium: scripts: make sure gfs2 can be configured using hawk (bsc#1067123) + * medium: bootstrap: fix init vgfs crash if no "-o device" option + * medium: bootstrap: fix init storage crash if no value input + * medium: ui_configure: fix crash when no args given + * medium: filter exist args + * low: utils: convert bytes to str (bsc#1067823) + * low: ui_context: Continue completing when input is an alias + * low: bootstrap: Change error/confirm message with specific device name + +------------------------------------------------------------------- @@ -17 +38 @@ - * low: bootstrap: Avoid printing None instead of NTP service name + * low: bootstrap: Avoid printing None instead of NTP service name (bsc#1060602) Old: ---- crmsh-4.0.0+git.1510563824.1aecfa01.tar.bz2 New: ---- crmsh-4.0.0+git.1511604050.816cb0f5.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.wgdQgB/_old 2017-11-27 22:19:09.365012437 +0100 +++ /var/tmp/diff_new_pack.wgdQgB/_new 2017-11-27 22:19:09.365012437 +0100 @@ -36,7 +36,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0+ Group: %{pkg_group} -Version: 4.0.0+git.1510563824.1aecfa01 +Version: 4.0.0+git.1511604050.816cb0f5 Release: 0 Url: http://crmsh.github.io Source0: %{name}-%{version}.tar.bz2 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.wgdQgB/_old 2017-11-27 22:19:09.413010696 +0100 +++ /var/tmp/diff_new_pack.wgdQgB/_new 2017-11-27 22:19:09.417010551 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/ClusterLabs/crmsh.git</param> - <param name="changesrevision">1aecfa01858a5a8edc303d9897a651eeaec23d80</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">816cb0f524860f165fc38cb95c92b10c26e6bba4</param></service></servicedata> \ No newline at end of file ++++++ crmsh-4.0.0+git.1510563824.1aecfa01.tar.bz2 -> crmsh-4.0.0+git.1511604050.816cb0f5.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/bootstrap.py new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/bootstrap.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/bootstrap.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/bootstrap.py 2017-11-25 11:00:50.000000000 +0100 @@ -138,7 +138,7 @@ drop_last_history() if match is None: return val - if re.match(match, val) is not None: + if val and re.match(match, val) is not None: if not valid_func or valid_func(val, prev_value): return val print(term.render(clidisplay.error(" Invalid value entered"))) @@ -881,7 +881,7 @@ for i in 0, 1: ringXaddr = prompt_for_string('Address for ring{}'.format(i), r'([0-9]+\.){3}[0-9]+|[0-9a-fA-F]{1,4}:', - "", + _context.ip_address if i == 0 and _context.ip_address else "", valid_ucastIP, ringXaddr_res) if not ringXaddr: @@ -1040,6 +1040,8 @@ """ @utils.memoize def check_amazon(): + if not is_program("dmidecode"): + return False _rc, outp = utils.get_stdout("dmidecode -s system-version") return re.search(r"\<.*\.amazon\>", outp) is not None @@ -1368,10 +1370,12 @@ Configure cluster OCFS2 device. """ dev = _context.ocfs2_device + if not dev: + error("vgfs stage requires -o <dev>") mntpoint = "/srv/clusterfs" if not is_block_device(dev): - error("OCFS2 device $OCFS2_DEVICE does not exist") + error("OCFS2 device \"{}\" does not exist".format(dev)) # TODO: configurable mountpoint and vg name crm_configure_load("update", """ @@ -1390,7 +1394,7 @@ _rc, blkid, _err = utils.get_stdout_stderr("blkid %s" % (dev)) if "TYPE" in blkid: - if not confirm("Exiting filesystem found on $OCFS2_DEVICE - destroy?"): + if not confirm("Exiting filesystem found on \"{}\" - destroy?".format(dev)): for res in ("base-clone", "c-clusterfs"): invoke("crm resource stop %s" % (res)) wait_for_stop("Waiting for resource %s to stop" % (res), res) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/cibconfig.py new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/cibconfig.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/cibconfig.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/cibconfig.py 2017-11-25 11:00:50.000000000 +0100 @@ -180,7 +180,7 @@ """ Copies the given nvpair into the given tag containing nvpairs """ - common_debug("copy_nvpair: %s" % (etree.tostring(nvp))) + common_debug("copy_nvpair: %s" % (xml_tostring(nvp))) if 'value' not in nvp.attrib: nvpairs.append(copy.deepcopy(nvp)) return @@ -219,7 +219,7 @@ else: tonode.append(copy.deepcopy(node)) - common_debug("copy_nvpairs: %s -> %s" % (etree.tostring(fromnode), etree.tostring(tonode))) + common_debug("copy_nvpairs: %s -> %s" % (xml_tostring(fromnode), xml_tostring(tonode))) id_hint = tonode.get('id') for c in fromnode: if is_comment(c): @@ -782,7 +782,7 @@ try: node.set('id', defid) except TypeError as e: - raise ValueError('Internal error: %s (%s)' % (e, etree.tostring(node))) + raise ValueError('Internal error: %s (%s)' % (e, xml_tostring(node))) obj_id = node.get('id') idmgmt.save(obj_id) if root.tag != "node" and obj_id and not is_id_valid(obj_id): @@ -806,7 +806,7 @@ # In this case, we need to delay postprocessing # until we know where to insert the op return node, obj_type, None - common_err("No ID found for %s: %s" % (obj_type, etree.tostring(node))) + common_err("No ID found for %s: %s" % (obj_type, xml_tostring(node))) return None, None, None if node.tag in constants.defaults_tags: node = node[0] @@ -1099,19 +1099,19 @@ with clidisplay.nopretty(): cli_text = self.repr_cli(format_mode=0) if not cli_text: - common_debug("validation failed: %s" % (etree.tostring(self.node))) + common_debug("validation failed: %s" % (xml_tostring(self.node))) return False xml2 = self.cli2node(cli_text) if xml2 is None: common_debug("validation failed: %s -> %s" % ( - etree.tostring(self.node), + xml_tostring(self.node), cli_text)) return False if not xml_equals(self.node, xml2, show=True): common_debug("validation failed: %s -> %s -> %s" % ( - etree.tostring(self.node), + xml_tostring(self.node), cli_text, - etree.tostring(xml2))) + xml_tostring(xml2))) return False return True @@ -2219,7 +2219,7 @@ is_node = item.tag == 'node' if obj_id is None: common_err("element %s has no id!" % - etree.tostring(item, pretty_print=True)) + xml_tostring(item, pretty_print=True)) return False elif is_node and obj_id in self._node_set: common_err("Duplicate node: %s" % (obj_id)) @@ -2412,7 +2412,7 @@ if schema.get('sub', obj.node.tag, 'a') is None: common_err("Element '%s' is not supported by the RNG schema %s" % (obj.node.tag, schema_st)) - common_debug("Offending object: %s" % (etree.tostring(obj.node))) + common_debug("Offending object: %s" % (xml_tostring(obj.node))) rc = False if not rc: # revert, as some elements won't validate @@ -2593,7 +2593,7 @@ cibadmin_opts = force and "-R --force" or "-R" rc = pipe_string("%s %s" % (cib_piped, cibadmin_opts), etree.tostring(conf_el)) if rc != 0: - update_err("cib", cibadmin_opts, etree.tostring(conf_el), rc) + update_err("cib", cibadmin_opts, xml_tostring(conf_el), rc) return False return True @@ -2630,7 +2630,7 @@ # produce a diff: # dump_new_conf | crm_diff -o self.cib_orig -n - - common_debug("Input: %s" % (etree.tostring(self.cib_elem))) + common_debug("Input: %s" % (xml_tostring(self.cib_elem))) rc, cib_diff = filter_string("%s -o %s -n -" % (self._crm_diff_cmd, tmpf), etree.tostring(self.cib_elem)) @@ -3350,7 +3350,7 @@ # FIXME: raise error? common_debug("create_from_cli (%s): failed" % (cli)) return None - common_debug("create_from_cli: %s, %s, %s" % (etree.tostring(elem), obj_type, obj_id)) + common_debug("create_from_cli: %s, %s, %s" % (xml_tostring(elem), obj_type, obj_id)) if obj_type in olist(constants.nvset_cli_names): return self.set_property_cli(obj_type, elem) if obj_type == "op": @@ -3402,14 +3402,14 @@ if not self._adjust_children(obj): return False if not obj.cli_use_validate(): - common_debug("update_element: validation failed (%s, %s)" % (obj, etree.tostring(newnode))) + common_debug("update_element: validation failed (%s, %s)" % (obj, xml_tostring(newnode))) obj.nocli_warn = True obj.nocli = True obj.set_updated() return True def merge_from_cli(self, obj, node): - common_debug("merge_from_cli: %s %s" % (obj.obj_type, etree.tostring(node))) + common_debug("merge_from_cli: %s %s" % (obj.obj_type, xml_tostring(node))) if obj.obj_type in constants.nvset_cli_names: rc = merge_attributes(obj.node, node, "nvpair") else: @@ -3461,7 +3461,7 @@ obj = self.create_from_cli(cli) if not obj: common_debug("create_from_cli '%s' failed" % - (etree.tostring(cli, pretty_print=True))) + (xml_tostring(cli, pretty_print=True))) return False test_l.append(obj) @@ -3479,7 +3479,7 @@ return False if not self.update_from_cli(obj, node, method): common_debug("update_from_cli failed: %s, %s, %s" % - (obj, etree.tostring(node), method)) + (obj, xml_tostring(node), method)) return False test_l.append(obj) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/constants.py new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/constants.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/constants.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/constants.py 2017-11-25 11:00:50.000000000 +0100 @@ -212,14 +212,16 @@ "restart-type", "description", "remote-node", "requires", "provides", "remote-port", "remote-addr", "remote-connect-timeout" ) -group_meta_attributes = ("container", ) -clone_meta_attributes = ( +common_meta_attributes = ("priority", "target-role", "is-managed") +group_meta_attributes = common_meta_attributes + ("container", ) +clone_meta_attributes = common_meta_attributes + ( "ordered", "notify", "interleave", "globally-unique", "clone-max", "clone-node-max", "clone-state", "description", "clone-min", ) -ms_meta_attributes = ( - "master-max", "master-node-max", "description", +ms_meta_attributes = common_meta_attributes + ( + "clone-max", "clone-node-max", "notify", "globally-unique", "ordered", + "interleave", "master-max", "master-node-max", "description", ) alert_meta_attributes = ( "timeout", "timestamp-format" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/ui_configure.py new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/ui_configure.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/ui_configure.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/ui_configure.py 2017-11-25 11:00:50.000000000 +0100 @@ -55,9 +55,27 @@ _top_rsc_id_list = compl.call(cib_factory.top_rsc_id_list) _node_id_list = compl.call(cib_factory.node_id_list) _rsc_template_list = compl.call(cib_factory.rsc_template_list) -_group_completer = compl.join(_f_prim_free_id_list, compl.choice(['params', 'meta'])) -_clone_completer = compl.choice(['params', 'meta']) -_ms_completer = compl.choice(['params', 'meta']) + + +def _advanced_completer(args): + ''' + meta completers for group/ms/clone resource type + ''' + key_words = ["meta", "params"] + completing = args[-1] + resource_type = args[0] + if completing.endswith('='): + # TODO add some help messages + return [] + keyw = last_keyword(args, key_words) + if keyw and keyw == "meta": + if resource_type == "group": + return [s+'=' for s in constants.group_meta_attributes] + key_words + if resource_type == "clone": + return [s+'=' for s in constants.clone_meta_attributes] + key_words + if resource_type in ["ms", "master"]: + return [s+'=' for s in constants.ms_meta_attributes] + key_words + return key_words def _list_resource(args): @@ -182,7 +200,8 @@ return [] elif '=' in completing: return [] - return [s+'=' for s in agent.params(completion=True)] + return [s+'=' for s in agent.params(completion=True) + if utils.any_startswith(args, s+'=') is None] def _prim_meta_completer(agent, args): @@ -191,7 +210,8 @@ return ['meta'] if '=' in completing: return [] - return [s+'=' for s in constants.rsc_meta_attributes] + return [s+'=' for s in constants.rsc_meta_attributes + if utils.any_startswith(args, s+'=') is None] def _prim_op_completer(agent, args): @@ -229,8 +249,9 @@ if args[-2] in actions: res = [] for k, v in actions[args[-2]].items(): + if args[-1].startswith(k+'='): + continue res += ["%s=%s" % (k, v)] - res.remove(args[-1]) return res return [] @@ -702,6 +723,8 @@ not cib_factory.is_elem_supported(cmd): common_err("%s not supported by the RNG schema" % cmd) return False + if not args: + return cib_factory.create_object(cmd, *args) if args[0].startswith("id="): object_id = args[0].strip("id=") else: @@ -739,7 +762,7 @@ return self.__conf_object(context.get_command_name(), *tuple(tmp)) @command.skill_level('administrator') - @command.completers_repeating(compl.attr_id, _group_completer) + @command.completers_repeating(compl.attr_id, _f_prim_free_id_list, _advanced_completer) def do_group(self, context, *args): """usage: group <name> <rsc> [<rsc>...] [params <param>=<value> [<param>=<value>...]] @@ -747,7 +770,7 @@ return self.__conf_object(context.get_command_name(), *args) @command.skill_level('administrator') - @command.completers_repeating(compl.attr_id, _f_children_id_list, _clone_completer) + @command.completers_repeating(compl.attr_id, _f_children_id_list, _advanced_completer) def do_clone(self, context, *args): """usage: clone <name> <rsc> [params <param>=<value> [<param>=<value>...]] @@ -756,7 +779,7 @@ @command.alias('master') @command.skill_level('administrator') - @command.completers_repeating(compl.attr_id, _f_children_id_list, _ms_completer) + @command.completers_repeating(compl.attr_id, _f_children_id_list, _advanced_completer) def do_ms(self, context, *args): """usage: ms <name> <rsc> [params <param>=<value> [<param>=<value>...]] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/ui_context.py new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/ui_context.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/ui_context.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/ui_context.py 2017-11-25 11:00:50.000000000 +0100 @@ -136,6 +136,8 @@ if not ret or self.command_info.aliases: if not token in self.current_level().get_completions(): return self.current_level().get_completions() + if self.command_name in self.command_info.aliases and not self.command_args: + return [self.command_name] return ret # reached the end on a valid level. # return the completions for the previous level. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/ui_resource.py new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/ui_resource.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/ui_resource.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/ui_resource.py 2017-11-25 11:00:50.000000000 +0100 @@ -638,7 +638,7 @@ def _remove_trace(self, rsc, op_node): from lxml import etree - common_debug("op_node: %s" % (etree.tostring(op_node))) + common_debug("op_node: %s" % (xmlutil.xml_tostring(op_node))) op_node = rsc.del_op_attr(op_node, constants.trace_ra_attr) if rsc.is_dummy_operation(op_node): rsc.del_operation(op_node) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/utils.py new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/utils.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/crmsh/utils.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/crmsh/utils.py 2017-11-25 11:00:50.000000000 +0100 @@ -42,6 +42,14 @@ return s +def any_startswith(iterable, prefix): + """Return first element in iterable which startswith prefix, or None.""" + for element in iterable: + if element.startswith(prefix): + return element + return None + + def memoize(function): "Decorator to invoke a function once only for any argument" memoized = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/data-manifest new/crmsh-4.0.0+git.1511604050.816cb0f5/data-manifest --- old/crmsh-4.0.0+git.1510563824.1aecfa01/data-manifest 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/data-manifest 2017-11-25 11:00:50.000000000 +0100 @@ -24,6 +24,7 @@ scripts/mailto/main.yml scripts/nfsserver-lvm-drbd/main.yml scripts/nfsserver/main.yml +scripts/nginx/main.yml scripts/ocfs2/main.yml scripts/oracle/main.yml scripts/raid1/main.yml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/scripts/gfs2/main.yml new/crmsh-4.0.0+git.1511604050.816cb0f5/scripts/gfs2/main.yml --- old/crmsh-4.0.0+git.1510563824.1aecfa01/scripts/gfs2/main.yml 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/scripts/gfs2/main.yml 2017-11-25 11:00:50.000000000 +0100 @@ -9,8 +9,6 @@ The file system should be on the device, unless cLVM is used. category: File System -include: - - script: gfs2-base parameters: - name: id shortdesc: File System Resource ID @@ -31,19 +29,34 @@ shortdesc: Mount Options type: string required: false + - name: dlm + shortdesc: Create DLM Resource and Cloned Group + longdesc: If set, create the DLM resource and cloned resource group. + type: boolean + default: true + - name: group + shortdesc: Cloned Group Resource ID + longdesc: ID of cloned group + required: false + type: resource + default: g-dlm actions: - - include: gfs2-base + - when: dlm + cib: | + primitive dlm ocf:pacemaker:controld + op start timeout=90 + op stop timeout=60 + group {{group}} dlm + clone c-dlm {{group}} meta interleave=true - cib: | - primitive {{id}} Filesystem - directory="{{directory}}" - device="{{device}}" - fstype=gfs2 - {{#options}}options="{{options}}"{{/options}} - op monitor interval=20s timeout=40s - - clone c-{{id}} {{id}} - meta interleave=true ordered=true + primitive {{id}} ocf:heartbeat:Filesystem + directory="{{directory}}" + fstype="gfs2" + device="{{device}}" + {{#options}}options="{{options}}"{{/options}} + op start timeout=60s + op stop timeout=60s + op monitor interval=20s timeout=40s - - crm: "configure modgroup {{gfs2-base:clvm-group}} add c-{{id}}" - shortdesc: Add cloned file system to cLVM group - when: "{{gfs2-base:clvm-group}}" + - crm: configure modgroup {{group}} add {{id}} + shortdesc: Add the GFS2 File System to the Cloned Group diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/scripts/nginx/main.yml new/crmsh-4.0.0+git.1511604050.816cb0f5/scripts/nginx/main.yml --- old/crmsh-4.0.0+git.1510563824.1aecfa01/scripts/nginx/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/scripts/nginx/main.yml 2017-11-25 11:00:50.000000000 +0100 @@ -0,0 +1,63 @@ +# Copyright (C) 2017 Xin Liang +# +# License: GNU General Public License (GPL) +version: 2.2 +category: Server +shortdesc: Nginx Webserver +longdesc: | + Configure a resource group containing a virtual IP address and + an instance of the Nginx web server. + + You can optionally configure a file system resource which will be + mounted before the web server is started. + + You can also optionally configure a database resource which will + be started before the web server but after mounting the optional + file system. +include: + - agent: ocf:heartbeat:nginx + name: nginx + longdesc: | + The Nginx configuration file specified here must be available via the + same path on all cluster nodes; And nginx.service should be disabled on + all cluster nodes; And "server_name" option in nginx configure file + should be related with virtual IP. + ops: | + op start timeout="40" + op stop timeout="60" + op monitor interval="10" timeout="30" + - script: virtual-ip + shortdesc: The IP address configured here will start before the Nginx instance. + parameters: + - name: id + value: "{{id}}-vip" + - script: filesystem + shortdesc: Optional file system mounted before the web server is started. + required: false + - script: database + shortdesc: Optional database started before the web server is started. + required: false +parameters: + - name: install + type: boolean + shortdesc: Install and configure nginx + value: false +actions: + - install: + - nginx + shortdesc: Install the nginx package + when: install + - service: + - apache: disable + shortdesc: Let cluster manage nginx + when: install + - include: filesystem + - include: database + - include: virtual-ip + - include: nginx + - cib: | + group g-{{id}} + {{filesystem:id}} + {{database:id}} + {{virtual-ip:id}} + {{id}} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/test/testcases/scripts.exp new/crmsh-4.0.0+git.1511604050.816cb0f5/test/testcases/scripts.exp --- old/crmsh-4.0.0+git.1510563824.1aecfa01/test/testcases/scripts.exp 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/test/testcases/scripts.exp 2017-11-25 11:00:50.000000000 +0100 @@ -11,6 +11,7 @@ ERROR: 2: Error when loading script haproxy: No meta-data for agent: systemd:haproxy .EXT crm_resource --show-metadata ocf:heartbeat:LVM .EXT crm_resource --show-metadata ocf:heartbeat:MailTo +.EXT crm_resource --show-metadata ocf:heartbeat:nginx .EXT crm_resource --show-metadata ocf:heartbeat:Raid1 Basic: @@ -53,6 +54,7 @@ Server: apache Apache Webserver +nginx Nginx Webserver Stonith: @@ -113,6 +115,7 @@ Server: apache Apache Webserver +nginx Nginx Webserver Stonith: @@ -138,6 +141,7 @@ mailto nfsserver nfsserver-lvm-drbd +nginx ocfs2 oracle raid-lvm @@ -170,6 +174,7 @@ mailto nfsserver nfsserver-lvm-drbd +nginx ocfs2 oracle raid-lvm @@ -206,6 +211,7 @@ mailto nfsserver nfsserver-lvm-drbd +nginx ocfs2 oracle raid-lvm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/utils/crm_pkg.py new/crmsh-4.0.0+git.1511604050.816cb0f5/utils/crm_pkg.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/utils/crm_pkg.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/utils/crm_pkg.py 2017-11-25 11:00:50.000000000 +0100 @@ -71,7 +71,7 @@ rc, stdout, stderr = run(cmd) if rc == 0: for line in stdout.splitlines(): - if name in line: + if name in line.decode('utf-8'): return line.strip() return None @@ -234,8 +234,8 @@ if exe: rc, stdout, stderr, changed = mgr().dispatch(pkg, state) return {'rc': rc, - 'stdout': stdout, - 'stderr': stderr, + 'stdout': stdout.decode('utf-8'), + 'stderr': stderr.decode('utf-8'), 'changed': changed } fail(msg="No supported package manager found") @@ -262,6 +262,6 @@ if not args.name or not args.state: raise IOError("Bad arguments: %s" % (sys.argv)) data = manage_package(args.name, args.state) - print(json.dumps(data)) + print(json.dumps(str(data))) main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/utils/crm_rpmcheck.py new/crmsh-4.0.0+git.1511604050.816cb0f5/utils/crm_rpmcheck.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/utils/crm_rpmcheck.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/utils/crm_rpmcheck.py 2017-11-25 11:00:50.000000000 +0100 @@ -15,7 +15,7 @@ stderr=subprocess.PIPE) out, err = proc.communicate(None) proc.wait() - return proc.returncode, out, err + return proc.returncode, out.decode('utf-8'), err.decode('utf-8') def package_data(pkg): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1510563824.1aecfa01/utils/crm_script.py new/crmsh-4.0.0+git.1511604050.816cb0f5/utils/crm_script.py --- old/crmsh-4.0.0+git.1510563824.1aecfa01/utils/crm_script.py 2017-11-13 10:03:44.000000000 +0100 +++ new/crmsh-4.0.0+git.1511604050.816cb0f5/utils/crm_script.py 2017-11-25 11:00:50.000000000 +0100 @@ -131,7 +131,7 @@ rc, out, err = sudo_call(['./crm_pkg.py', '-n', name, '-s', state]) if rc != 0: raise IOError("%s / %s" % (out, err)) - outp = json.loads(out) + outp = json.loads(out.decode('utf-8')) if isinstance(outp, dict) and 'rc' in outp: rc = int(outp['rc']) if rc != 0: