Hello community, here is the log from the commit of package yast2-cluster for openSUSE:Factory checked in at 2019-10-16 09:18:52 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-cluster (Old) and /work/SRC/openSUSE:Factory/.yast2-cluster.new.2352 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-cluster" Wed Oct 16 09:18:52 2019 rev:36 rq:738720 version:4.2.5 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-cluster/yast2-cluster.changes 2019-09-30 15:58:18.721390182 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-cluster.new.2352/yast2-cluster.changes 2019-10-16 09:18:53.614909602 +0200 @@ -1,0 +2,17 @@ +Fri Oct 11 07:48:01 UTC 2019 - Yuan Ren <[email protected]> + +- bsc#1149089 corosync-qdevice service ready to be configured + * Add corosync-qdevice RPM package into Yast2-cluster + * Add `IP Version` option in Dialog + * Member Address is enabled whatever transport and ip version + * Member Address is required/optional relations based on different transport or IP version used + * Auto Generate Node ID would disabled once IPV6 selected + * Auto Generate Node ID is required if UDP&IPv4&Member Address is empty + * When enable corosync-qdevice but Member Address is empty, a warning would occur + * Corosync-qdevice algorithm can only choose ffsplit + * Qdevice votes disabled to be set mannually, defualt is "1" + * expected_votes should be enabled only in nodelist empty&ipv4&udp + * Add corosync-qdevice service start/stop/status and enabale/disable at booting time +- Version 4.2.5 + +------------------------------------------------------------------- Old: ---- yast2-cluster-4.2.4.tar.bz2 New: ---- yast2-cluster-4.2.5.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-cluster.spec ++++++ --- /var/tmp/diff_new_pack.Vzdw5u/_old 2019-10-16 09:18:55.326905190 +0200 +++ /var/tmp/diff_new_pack.Vzdw5u/_new 2019-10-16 09:18:55.358905108 +0200 @@ -19,7 +19,7 @@ %define _fwdefdir %{_libexecdir}/firewalld/services Name: yast2-cluster -Version: 4.2.4 +Version: 4.2.5 Release: 0 Summary: Configuration of cluster License: GPL-2.0-only @@ -34,7 +34,6 @@ BuildRequires: yast2-devtools >= 4.2.2 BuildRequires: rubygem(%{rb_default_ruby_abi}:yast-rake) -Requires: yast2 >= 4.0.39 Requires: yast2 >= 4.1.3 Requires: yast2-ruby-bindings >= 1.0.0 ++++++ yast2-cluster-4.2.4.tar.bz2 -> yast2-cluster-4.2.5.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-cluster-4.2.4/package/yast2-cluster.changes new/yast2-cluster-4.2.5/package/yast2-cluster.changes --- old/yast2-cluster-4.2.4/package/yast2-cluster.changes 2019-09-27 14:29:06.000000000 +0200 +++ new/yast2-cluster-4.2.5/package/yast2-cluster.changes 2019-10-16 05:12:19.000000000 +0200 @@ -1,4 +1,21 @@ ------------------------------------------------------------------- +Fri Oct 11 07:48:01 UTC 2019 - Yuan Ren <[email protected]> + +- bsc#1149089 corosync-qdevice service ready to be configured + * Add corosync-qdevice RPM package into Yast2-cluster + * Add `IP Version` option in Dialog + * Member Address is enabled whatever transport and ip version + * Member Address is required/optional relations based on different transport or IP version used + * Auto Generate Node ID would disabled once IPV6 selected + * Auto Generate Node ID is required if UDP&IPv4&Member Address is empty + * When enable corosync-qdevice but Member Address is empty, a warning would occur + * Corosync-qdevice algorithm can only choose ffsplit + * Qdevice votes disabled to be set mannually, defualt is "1" + * expected_votes should be enabled only in nodelist empty&ipv4&udp + * Add corosync-qdevice service start/stop/status and enabale/disable at booting time +- Version 4.2.5 + +------------------------------------------------------------------- Wed Sep 25 07:06:51 UTC 2019 - nick wang <[email protected]> - bsc#1151687, update the open ports to support pacemaker-remote, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-cluster-4.2.4/package/yast2-cluster.spec new/yast2-cluster-4.2.5/package/yast2-cluster.spec --- old/yast2-cluster-4.2.4/package/yast2-cluster.spec 2019-09-27 14:29:06.000000000 +0200 +++ new/yast2-cluster-4.2.5/package/yast2-cluster.spec 2019-10-16 05:12:19.000000000 +0200 @@ -18,7 +18,7 @@ %define _fwdefdir %{_libexecdir}/firewalld/services Name: yast2-cluster -Version: 4.2.4 +Version: 4.2.5 Release: 0 Summary: Configuration of cluster License: GPL-2.0-only @@ -33,7 +33,6 @@ BuildRequires: update-desktop-files BuildRequires: yast2-devtools >= 4.2.2 -Requires: yast2 >= 4.0.39 Requires: yast2-ruby-bindings >= 1.0.0 Requires: yast2 >= 4.1.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-cluster-4.2.4/src/include/cluster/dialogs.rb new/yast2-cluster-4.2.5/src/include/cluster/dialogs.rb --- old/yast2-cluster-4.2.4/src/include/cluster/dialogs.rb 2019-09-27 14:29:06.000000000 +0200 +++ new/yast2-cluster-4.2.5/src/include/cluster/dialogs.rb 2019-10-16 05:12:19.000000000 +0200 @@ -70,6 +70,12 @@ @usable_interface = [] end + # IP check between address and IP Version + def ip_matching_check(ip_address, ip_version) + return (ip_version.to_s == "ipv4" && IP.Check4(ip_address.to_s)) || + (ip_version.to_s == "ipv6" && IP.Check6(ip_address.to_s)) + end + # return `cancel or a string def text_input_dialog(title, value) ret = nil @@ -152,7 +158,9 @@ def ValidNodeID if Cluster.memberaddr.size <= 0 - return true + UI.SetFocus(:nodeid) + Popup.Message(_("Auto Generate Node ID has to be selected")) + return false end i = 0 @@ -161,7 +169,7 @@ Builtins.foreach(Cluster.memberaddr) do |value| if value[:nodeid].to_i <= 0 - Popup.Message(_("Node ID has to be fulfilled with a positive integer")) + Popup.Message(_("Node ID has to be fulfilled with a positive integer or select Auto Generate Node ID")) UI.ChangeWidget(:memberaddr, :CurrentItem, i) i = 0 raise Break @@ -188,6 +196,7 @@ # BNC#871970, change member address struct def ValidateCommunication i = 0 + ip_version = UI.QueryWidget(Id(:ip_version), :Value) if UI.QueryWidget(Id(:cluster_name), :Value) == "" Popup.Message(_("The cluster name has to be fulfilled")) @@ -195,42 +204,33 @@ return false end - if UI.QueryWidget(Id(:transport), :Value) == "udpu" - i = 0 - Builtins.foreach(Cluster.memberaddr) do |value| - if !IP.Check(value[:addr1]) || ( UI.QueryWidget(Id(:enable2), :Value) && !IP.Check(value[:addr2]) ) - UI.ChangeWidget(:memberaddr, :CurrentItem, i) - i = 0 - raise Break - end - i = Ops.add(i, 1) - end - if i == 0 - UI.SetFocus(:memberaddr) - Popup.Message(_("The Member Address has to be fulfilled")) - return false - end - else - #BNC#880242, expected_votes must have value when "udp" - if UI.QueryWidget(Id(:expected_votes), :Value) == "" - Popup.Message(_("The Expected Votes has to be fulfilled when multicast transport is configured")) - UI.SetFocus(:expected_votes) - return false - end + if UI.QueryWidget(Id(:transport), :Value) == "udp" - if IP.Check(Convert.to_string(UI.QueryWidget(Id(:bindnetaddr1), :Value))) == false - Popup.Message(_("The Bind Network Address has to be fulfilled")) + if !ip_matching_check(UI.QueryWidget(Id(:bindnetaddr1), :Value), ip_version) + Popup.Message(_("IP Version doesn't match with Bind Network Address in Channel")) UI.SetFocus(:bindnetaddr1) return false end - if !IP.Check(Convert.to_string(UI.QueryWidget(Id(:mcastaddr1), :Value))) - Popup.Message(_("The Multicast Address has to be fulfilled")) + if !ip_matching_check(UI.QueryWidget(Id(:mcastaddr1), :Value), ip_version) + Popup.Message(_("IP Version doesn't match with Multicast Address in Channel")) UI.SetFocus(:mcastaddr1) return false end end + if Cluster.memberaddr.size <= 0 + if UI.QueryWidget(Id(:transport), :Value) == "udpu" || ip_version.to_s == "ipv6" + Popup.Message(_("Member address is required")) + return false + #BNC#880242, expected_votes must have value when "udp" without nodelist + elsif UI.QueryWidget(Id(:expected_votes), :Value) == "" + Popup.Message(_("The Expected Votes has to be fulfilled when multicast transport is configured without nodelist")) + UI.SetFocus(:expected_votes) + return false + end + end + if !Builtins.regexpmatch( Convert.to_string(UI.QueryWidget(Id(:mcastport1), :Value)), "^[0-9]+$" @@ -242,18 +242,14 @@ if UI.QueryWidget(Id(:enable2), :Value) if UI.QueryWidget(Id(:transport), :Value) == "udp" - if IP.Check( - Convert.to_string(UI.QueryWidget(Id(:bindnetaddr2), :Value)) - ) == false - Popup.Message(_("The Bind Network Address has to be fulfilled")) + if !ip_matching_check(UI.QueryWidget(Id(:bindnetaddr2), :Value), ip_version) + Popup.Message(_("IP Version doesn't match with Bind Network Address in Redundant Channel")) UI.SetFocus(:bindnetaddr2) return false end - if IP.Check( - Convert.to_string(UI.QueryWidget(Id(:mcastaddr2), :Value)) - ) == false - Popup.Message(_("The Multicast Address has to be fulfilled")) + if !ip_matching_check(UI.QueryWidget(Id(:mcastaddr2), :Value), ip_version) + Popup.Message(_("IP Version doesn't match with Multicast Address in Redundant Channel")) UI.SetFocus(:mcastaddr2) return false end @@ -278,14 +274,29 @@ end end - if !UI.QueryWidget(Id(:autoid), :Value ) && ( UI.QueryWidget(Id(:transport), :Value) == "udpu" ) + Builtins.foreach(Cluster.memberaddr) do |value| + if !ip_matching_check(value[:addr1], ip_version) || + (UI.QueryWidget(Id(:enable2), :Value) && !ip_matching_check(value[:addr2], ip_version)) + UI.ChangeWidget(:memberaddr, :CurrentItem, i) + if Cluster.memberaddr.size <= 0 && (UI.QueryWidget(Id(:transport), :Value) == "udp" && ip_version.to_s == "ipv4") + raise Break + else + UI.SetFocus(:memberaddr) + Popup.Message(_("IP Version doesn't match with addresses within Member Address")) + i = 0 + return false + end + end + i += 1 + end + + if !UI.QueryWidget(Id(:autoid), :Value ) ret = ValidNodeID() if !ret UI.SetFocus(Id(:memberaddr)) return false end end - true end @@ -361,6 +372,7 @@ Cluster.transport = Convert.to_string( UI.QueryWidget(Id(:transport), :Value) ) + Cluster.ip_version = UI.QueryWidget(Id(:ip_version), :Value).to_s #BNC#871970, clear second IP when redundant channel is disabled if !UI.QueryWidget(Id(:enable2), :Value) @@ -384,6 +396,17 @@ ) end + def expectedvotes_switch + if Cluster.memberaddr.size <= 0 && + UI.QueryWidget(Id(:ip_version), :Value).to_s == "ipv4" && + UI.QueryWidget(Id(:transport), :Value) == "udp" + UI.ChangeWidget(Id(:expected_votes), :Enabled, true) + else + UI.ChangeWidget(Id(:expected_votes), :Value, "") + UI.ChangeWidget(Id(:expected_votes), :Enabled, false) + end + end + # BNC#871970, change member address struct to memberaddr def transport_switch @@ -394,16 +417,20 @@ enable2 = udp && enable2 UI.ChangeWidget(Id(:mcastaddr1), :Enabled, enable1) - UI.ChangeWidget(Id(:memberaddr), :Enabled, !enable1) - UI.ChangeWidget(Id(:memberaddr_add), :Enabled, !enable1) - UI.ChangeWidget(Id(:memberaddr_del), :Enabled, !enable1) - UI.ChangeWidget(Id(:memberaddr_edit), :Enabled, !enable1) UI.ChangeWidget(Id(:mcastaddr2), :Enabled, enable2) UI.ChangeWidget(Id(:bindnetaddr1), :Enabled, enable1) UI.ChangeWidget(Id(:bindnetaddr2), :Enabled, enable2) + ip = UI.QueryWidget(Id(:ip_version), :Value).to_s + if ip == "ipv6" + UI.ChangeWidget(Id(:autoid), :Value, false) + UI.ChangeWidget(Id(:autoid), :Enabled, false) + else + UI.ChangeWidget(Id(:autoid), :Enabled, true) + end + nil end @@ -440,14 +467,27 @@ end end - transport = ComboBox( - Id(:transport), - Opt(:hstretch, :notify), - _("Transport:"), - [ - Item(Id("udp"),"Multicast"), - Item(Id("udpu"),"Unicast") - ] + hid = VBox( + HBox( + ComboBox( + Id(:transport), + Opt(:hstretch, :notify), + _("Transport:"), + [ + Item(Id("udp"), "Multicast"), + Item(Id("udpu"), "Unicast") + ] + ), + ComboBox( + Id(:ip_version), + Opt(:hstretch, :notify), + _("IP Version:"), + [ + Item(Id("ipv4"), "IPv4"), + Item(Id("ipv6"), "IPv6") + ] + ) + ) ) iface = Frame( @@ -511,7 +551,7 @@ )) contents = VBox( - transport, + HBox(hid), HBox(HWeight(1, VBox(iface)), HWeight(1, VBox(riface))), ip_table, HBox(nid), @@ -530,9 +570,10 @@ UI.ChangeWidget(Id(:autoid), :Value, Cluster.autoid) UI.ChangeWidget(Id(:cluster_name), :Value, Cluster.cluster_name) UI.ChangeWidget(Id(:expected_votes), :Value, Cluster.expected_votes) - UI.ChangeWidget(:expected_votes, :ValidChars, "0123456789"); + UI.ChangeWidget(:expected_votes, :ValidChars, "0123456789") UI.ChangeWidget(Id(:transport), :Value, Cluster.transport) + UI.ChangeWidget(Id(:ip_version), :Value, Cluster.ip_version) UI.ChangeWidget(Id(:rrpmode), :Value, Cluster.rrpmode) if "none" == Cluster.rrpmode @@ -587,25 +628,10 @@ while true fill_memberaddr_entries transport_switch + expectedvotes_switch ret = UI.UserInput - if ret == :bindnetaddr1 || ret == :bindnetaddr2 || ret == :mcastaddr1 || - ret == :mcastaddr2 - ip6 = false - netaddr = Convert.to_string(UI.QueryWidget(Id(ret), :Value)) - ip6 = IP.Check6(netaddr) - if ip6 - Cluster.ip_version = "ipv6" - UI.ChangeWidget(Id(:autoid), :Value, false) - UI.ChangeWidget(Id(:autoid), :Enabled, false) - else - Cluster.ip_version = "ipv4" - UI.ChangeWidget(Id(:autoid), :Enabled, true) - end - next - end - if ret == :enable2 if UI.QueryWidget(Id(:enable2), :Value) # Changewidget items will change value to first one automatically @@ -720,12 +746,6 @@ return false end - if UI.QueryWidget(Id(:qdevice_votes), :Value).to_i <= 0 - Popup.Message(_("Qdevice votes must be a positive integer")) - UI.SetFocus(:qdevice_votes) - return false - end - if !IP.Check(UI.QueryWidget(Id(:qdevice_host), :Value)) Popup.Message(_("Qdevice host mush have a valid IP address")) UI.SetFocus(:qdevice_host) @@ -738,13 +758,6 @@ return false end - if !["ffsplit", "lms", "test", "2nodelms"].include?(UI.QueryWidget(Id(:qdevice_algorithm), :Value)) - Popup.Message(_("The algorithm only can be one of the ffsplit, lms, test or 2nodelms." \ - "YaST will overwrite test and 2nodelms.")) - UI.SetFocus(Id(:algorithm)) - return false - end - if !["lowest", "highest"].include?(UI.QueryWidget(Id(:qdevice_tie_breaker), :Value)) && (UI.QueryWidget(Id(:qdevice_tie_breaker), :Value).to_i <= 0) Popup.Message(_("The tie breaker can be one of lowest, highest or a valid node id (number)")) @@ -752,6 +765,10 @@ return false end + if UI.QueryWidget(Id(:corosync_qdevice), :Value) && Cluster.memberaddr.size <= 0 + Popup.Message(_("Member Address is required when enable corosync qdevice")) + end + true end @@ -759,8 +776,6 @@ Cluster.corosync_qdevice = Convert.to_boolean(UI.QueryWidget(Id(:corosync_qdevice), :Value)) Cluster.qdevice_model = UI.QueryWidget(Id(:qdevice_model), :Value) - Cluster.qdevice_votes = UI.QueryWidget(Id(:qdevice_votes), :Value).to_s - Cluster.qdevice_host = UI.QueryWidget(Id(:qdevice_host), :Value) Cluster.qdevice_port = UI.QueryWidget(Id(:qdevice_port), :Value).to_s Cluster.qdevice_tls = UI.QueryWidget(Id(:qdevice_tls), :Value) @@ -771,15 +786,12 @@ def CorosyncQdeviceLayout qdevice_section = VBox( - HBox( - ComboBox( - Id(:qdevice_model), - Opt(:hstretch), - _("Qdevice model:"), - ["net"] - ), - Left(InputField(Id(:qdevice_votes),Opt(:hstretch), _("Qdevice votes:"),"")) - ) + Left(ComboBox( + Id(:qdevice_model), + Opt(:hstretch), + _("Qdevice model:"), + ["net"] + )) ) qdevice_net_section = VBox( @@ -793,13 +805,7 @@ Id(:qdevice_tls), Opt(:hstretch), _("TLS:"), ["off", "on", "required"] )), - Left(ComboBox( - Id(:qdevice_algorithm), Opt(:hstretch, :notify), _("Algorithm:"), - [ - Item(Id("ffsplit"), "ffsplit"), - Item(Id("lms"), "lms") - ] - )), + Left(ComboBox(Id(:qdevice_algorithm),Opt(:hstretch, :notify), _("Algorithm:"),["ffsplit"])), HSpacing(1), Left(InputField(Id(:qdevice_tie_breaker),Opt(:hstretch), _("Tie breaker:"),"lowest")) ) @@ -813,9 +819,7 @@ _("En&able Corosync Qdevice"), false, VBox( - VSpacing(1), qdevice_section, - VSpacing(2), qdevice_net_section, ) ), @@ -827,13 +831,15 @@ UI.ChangeWidget(Id(:corosync_qdevice), :Value, Cluster.corosync_qdevice) UI.ChangeWidget(Id(:qdevice_model), :Value, Cluster.qdevice_model) - UI.ChangeWidget(Id(:qdevice_votes), :Value, Cluster.qdevice_votes) - UI.ChangeWidget(Id(:qdevice_votes), :ValidChars, "0123456789"); UI.ChangeWidget(Id(:qdevice_host), :Value, Cluster.qdevice_host) UI.ChangeWidget(Id(:qdevice_port), :Value, Cluster.qdevice_port) UI.ChangeWidget(Id(:qdevice_tls), :Value, Cluster.qdevice_tls) UI.ChangeWidget(Id(:qdevice_algorithm), :Value, Cluster.qdevice_algorithm) + # As for now, ffsplit is only can be configuried withing Yast (sync with crmsh) + if UI.QueryWidget(Id(:qdevice_algorithm), :Value) == "ffsplit" + Cluster.qdevice_votes = "1" + end UI.ChangeWidget(Id(:qdevice_tie_breaker), :Value, Cluster.qdevice_tie_breaker) nil @@ -857,7 +863,6 @@ CorosyncQdeviceLayout() while true - UpdateQdeviceVotes() ret = UI.UserInput @@ -1010,22 +1015,49 @@ end def UpdateServiceStatus - ret = 0 - ret = Service.Status("pacemaker") - if ret == 0 + ret_pacemaker = 0 + ret_qdevice = 0 + ret_pacemaker = Service.Status("pacemaker") + if Cluster.corosync_qdevice && ret_pacemaker == 0 + ret_qdevice = Service.Status("corosync-qdevice") + # corosync-qdevice stop/start + if ret_qdevice == 0 + UI.ChangeWidget(Id(:status_qdevice), :Value, _("Running")) + UI.ChangeWidget(Id("start_qdevice_now"), :Enabled, false) + UI.ChangeWidget(Id("stop_qdevice_now"), :Enabled, true) + else + UI.ChangeWidget(Id(:status_qdevice), :Value, _("Not running")) + UI.ChangeWidget(Id("start_qdevice_now"), :Enabled, true) + UI.ChangeWidget(Id("stop_qdevice_now"), :Enabled, false) + end + else + UI.ChangeWidget(Id(:status_qdevice), :Value, _("Not configured")) + UI.ChangeWidget(Id("start_qdevice_now"), :Enabled, false) + UI.ChangeWidget(Id("stop_qdevice_now"), :Enabled, false) + end + # pacemaker&corosync stop/start + if ret_pacemaker == 0 UI.ChangeWidget(Id(:status), :Value, _("Running")) + UI.ChangeWidget(Id("start_now"), :Enabled, false) + UI.ChangeWidget(Id("stop_now"), :Enabled, true) else UI.ChangeWidget(Id(:status), :Value, _("Not running")) + UI.ChangeWidget(Id("start_now"), :Enabled, true) + UI.ChangeWidget(Id("stop_now"), :Enabled, false) end - UI.ChangeWidget(Id("start_now"), :Enabled, ret != 0) - UI.ChangeWidget(Id("stop_now"), :Enabled, ret == 0) - if not Service.Enabled("pacemaker") - UI.ChangeWidget(Id("off"), :Value, true) - UI.ChangeWidget(Id("on"), :Value, false) + ret_qdevice_booting = true + if Cluster.corosync_qdevice + ret_qdevice_booting = Service.Enabled("corosync-qdevice") + end + if Service.Enabled("pacemaker") && ret_qdevice_booting + UI.ChangeWidget(Id(:status_booting), :Value, _("Enabling")) + UI.ChangeWidget(Id("on"), :Enabled, false) + UI.ChangeWidget(Id("off"), :Enabled, true) else - UI.ChangeWidget(Id("on"), :Value, true) - UI.ChangeWidget(Id("off"), :Value, false) + UI.ChangeWidget(Id(:status_booting), :Value, _("Disabling")) + UI.ChangeWidget(Id("on"), :Enabled, true) + UI.ChangeWidget(Id("off"), :Enabled, false) end nil @@ -1051,37 +1083,38 @@ contents = VBox( VSpacing(1), Frame( - _("Booting"), - RadioButtonGroup( - Id("bootcorosync"), - HBox( - HSpacing(1), - VBox( - Left( - RadioButton( - Id("on"), - Opt(:notify), - _("On -- Start pacemaker during boot") - ) - ), - Left( - RadioButton( - Id("off"), - Opt(:notify), - _("Off -- Start pacemaker manually") + _("Cluster start at booting time enable/disable"), + Left( + VBox( + Left( + HBox( + HSpacing(1), + Label(_("Current Status: ")), + Label(Id(:status_booting), _("Enabling")), + ReplacePoint(Id("status_rp"), Empty()) + ) + ), + Left( + HBox( + HSpacing(1), + HBox( + PushButton(Id("on"), _("Enable cluster")), + PushButton(Id("off"), _("Disable cluster")) ) ) ) ) ) ), + VSpacing(1), Frame( - _("Switch On and Off"), + _("Pacemaker and corosync start/stop"), Left( VBox( Left( HBox( + HSpacing(1), Label(_("Current Status: ")), Label(Id(:status), _("Running")), ReplacePoint(Id("status_rp"), Empty()) @@ -1091,8 +1124,33 @@ HBox( HSpacing(1), HBox( - PushButton(Id("start_now"), _("Start pacemaker Now")), - PushButton(Id("stop_now"), _("Stop pacemaker Now")) + PushButton(Id("start_now"), _("Start Now")), + PushButton(Id("stop_now"), _("Stop Now")) + ) + ) + ) + ) + ) + ), + VSpacing(1), + Frame( + _("corosync-qdevice start/stop"), + Left( + VBox( + Left( + HBox( + HSpacing(1), + Label(_("Current Status: ")), + Label(Id(:status_qdevice), _("Running")), + ReplacePoint(Id("status_rp_qdevice"), Empty()) + ) + ), + Left( + HBox( + HSpacing(1), + HBox( + PushButton(Id("start_qdevice_now"), _("Start Now")), + PushButton(Id("stop_qdevice_now"), _("Stop Now")) ) ) ) @@ -1118,30 +1176,51 @@ if ret == "on" Service.Enable("pacemaker") + if Cluster.corosync_qdevice + Service.Enable("corosync-qdevice") + end next end if ret == "off" Service.Disable("pacemaker") + if Cluster.corosync_qdevice + Service.Disable("corosync-qdevice") + end next end # pacemaker will start corosync automatically. - # BNC#872651 is fixed, so stop pacemaker could stop corosync at the same time. if ret == "start_now" Cluster.save_csync2_conf Cluster.SaveClusterConfig - # BNC#872651 , add more info about error message + # BNC#872652 , add more info about error message Report.Error(Service.Error + errormsg) if !Service.Start("pacemaker") next end + # corosync-qdevice start + if ret == "start_qdevice_now" + Cluster.save_csync2_conf + Cluster.SaveClusterConfig + # reload the corosync.conf before starting qdevice within already started corosync + %x(corosync-cfgtool -R) + sleep(1) + Report.Error(Service.Error + errormsg) if !Service.Start("corosync-qdevice") + next + end + # pacemaker&corosync stop if ret == "stop_now" # BNC#874563,stop pacemaker could stop corosync since BNC#872651 is fixed # In bnc#1144200, the patch is dropped in corosync, so stop pacemaker not working Report.Error(Service.Error + errormsg) if !Service.Stop("corosync") next end + # corosync-qdevice stop + if ret == "stop_qdevice_now" + Report.Error(Service.Error + errormsg) if !Service.Stop("corosync-qdevice") + next + end if ret == :next || ret == :back val = ValidateService() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-cluster-4.2.4/src/include/cluster/helps.rb new/yast2-cluster-4.2.5/src/include/cluster/helps.rb --- old/yast2-cluster-4.2.4/src/include/cluster/helps.rb 2019-09-27 14:29:06.000000000 +0200 +++ new/yast2-cluster-4.2.5/src/include/cluster/helps.rb 2019-10-16 05:12:19.000000000 +0200 @@ -33,6 +33,7 @@ # All helps are here @HELPS = { "communication" => _( + "<p><b><big>IP Version</big></b><br>Specifies version of IP to use for communication. Value can be one of ipv4 or ipv6. Default (if unspecified) is ipv4.<br></p>\n" + "<p><b><big>Bind Network Address</big></b><br>This specifies the address which the openais executive should bind. This address should always end in zero. If the totem traffic should be routed over 192.168.5.92, set bindnetaddr to 192.168.5.0.<br>This may also be an IPV6 address, in which case IPV6 networking will be used. In this case, the full address must be specified and there is no automatic selection of the network interface within a specific subnet as with IPv4. If IPv6 networking is used, the nodeid field must be specified.<br></p>\n" + "<p><b><big>Multicast Address</big></b><br>This is the multicast address used by openais executive. The default should work for most networks, but the network administrator should be queried about a multicast address to use. Avoid 224.x.x.x because this is a \"config\" multicast address.<br>This may also be an IPV6 multicast address, in which case IPV6 networking will be used. If IPv6 networking is used, the nodeid field must be specified.</p>\n" + "<p><b><big>Port</big></b><br>This specifies the UDP port number. It is possible to use the same multicast address on a network with the openais services configured for different UDP ports.<br></p>\n" + @@ -40,12 +41,11 @@ "<p><b><big>Node ID</big></b><br>This configuration option is optional when using IPv4 and required when using IPv6. This is a 32 bit value specifying the node identifier delivered to the cluster membership service. If this is not specified with IPv4, the node id will be determined from the 32 bit IP address the system to which the system is bound with ring identifier of 0. The node identifier value of zero is reserved and should not be used.<br></p>\n" + "<p><b><big>rrp_mode</big></b><br>This specifies the mode of redundant ring, which may be none, active, or passive. Active replication offers slightly lower latency from transmit to delivery in faulty network environments but with less performance. Passive replication may nearly double the speed of the totem protocol if the protocol doesn't become cpu bound. The final option is none, in which case only one network interface will be used to operate the totem protocol. If only one interface directive is specified, none is automatically chosen. If multiple interface directives are specified, only active or passive may be chosen.<br></p>\n" + "<p><b><big>Cluster Name</big></b><br>This specifies the name of cluster and it's used for automatic generating of multicast address. Default is hacluster. For a geo cluster, each cluster must have a unique name.<br></p>\n" + - "<p><b><big>Expected votes</big></b><br>Expect vote number for voting quorum. Will be automatically calculated when the nodelist {} section is present in corosync.conf (the list will be generated when using unicast transport) or can be specified in the quorum {} section (Expect votes should use the total node numble of the cluster). If Expected votes presents in unicast transport, the value will override the one automatically calculated.<br></p>\n" + + "<p><b><big>Expected votes</big></b><br>Expect vote number for voting quorum. Will be automatically calculated when the nodelist {} section is present in corosync.conf (the list will be generated when using unicast transport) or can be specified in the quorum {} section (Expect votes should use the total node numble of the cluster). If Expected votes presents in unicast transport, the value will override the one automatically calculated. For safety, the Expected votes will be disabled once nodelist not empty, it's good for ignore the inappropriate Expected votes set.<br></p>\n" + "<p><b><big>Auto Generate Node ID</big></b><br>Nodeid is required when using IPv6. Auto node ID enabled will generate nodeid automatically.<br></p>\n" ), "corosyncqdevice" => _( "<p><b><big>Model</big></b><br>Specifies the model to be used. This parameter is required. corosync-qdevice is modular and is able to support multiple different models. The model basically defines what type of arbitrator is used. Currently only 'net' is supported.</p>\n" + - "<p><b><big>Votes</big></b><br>The number of votes provided to the cluster by qdevice. It should be configured as 1 when using 'ffsplit' algorithm and sum(votes_per_node) - 1 when 'lms' algorithm. Default is 1 or (number_of_nodes - 1) or generally sum(votes_per_node) - 1 based on algorithm.</p>\n" + "<p><b><big>Host</big></b><br>Specifies the IP address or host name of the qnetd server to be used. This parameter is required.</p>\n" + "<p><b><big>Port</big></b><br>Specifies TCP port of qnetd server. Default is 5403.</p>\n" + "<p><b><big>TLS</big></b><br>Can be one of 'on', 'off' or 'required' and specifies if tls should be used. 'on' means a connection with TLS is attempted first, but if the server doesn't advertise TLS support then non-TLS will be used. 'off' is used then TLS is not required and it's then not even tried. This mode is the only one which doesn't need a properly initialized NSS database. 'required' means TLS is required and if the server doesn't support TLS, qdevice will exit with error message. 'on' need manually change, refer to corosync-qdevice's man page for more details. Default is 'off' in yast.</p>\n" + @@ -58,7 +58,8 @@ ), "service" => _( "\n" + - "\t\t\t<p><b><big>Booting</big></b><br>Starting corosync service during boot or not</p>\n" + + "\t\t\t<p><b><big>Cluster start at booting time enable/disable</big></b><br>Start or not start the whole cluster at booting time. Service include: pacemaker, corosync, corosync-qdevice(If enabled corosyncqdevice).</p>\n" + + "\t\t\t<p><b><big>Cluster start/stop now</big></b><br>Start or stop the whole cluster right now. Service include: pacemaker, corosync, corosync-qdevice(If enabled corosyncqdevice).</p>\n" + "\t\t\t<p><b><big>Firewall Settings</big></b><br>Enable the port when Firewall is enabled</p>\n" + "\t\t\t" ), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-cluster-4.2.4/src/modules/Cluster.rb new/yast2-cluster-4.2.5/src/modules/Cluster.rb --- old/yast2-cluster-4.2.4/src/modules/Cluster.rb 2019-09-27 14:29:06.000000000 +0200 +++ new/yast2-cluster-4.2.5/src/modules/Cluster.rb 2019-10-16 05:12:19.000000000 +0200 @@ -96,6 +96,7 @@ # {:addr1=>"10.16.35.104",:nodeid=>"4" }, # {:addr1=>"10.16.35.105",:nodeid=>"5" }] @memberaddr = [] + @address = [] @corosync_qdevice = false @@ -200,17 +201,17 @@ @transport = SCR.Read(path(".openais.totem.transport")) @transport = "udp" if @transport == nil + @address = SCR.Read(path(".openais.nodelist.node")).split(" ") interfaces = SCR.Dir(path(".openais.totem.interface")) Builtins.foreach(interfaces) do |interface| if interface == "interface0" - if @transport == "udpu" + if @address != [] # BNC#871970, change member addresses to nodelist structure # memberaddr of udpu only read in interface0 # address is like "123.3.21.32;156.32.123.1:1 123.3.21.54;156.32.123.4:2 # 123.3.21.44;156.32.123.9" - address = SCR.Read(path(".openais.nodelist.node")).split(" ") - address.each do |addr| + @address.each do |addr| p = addr.split("-") if p[1] != nil q = p[0].split(";") @@ -228,8 +229,9 @@ end end end # end address.each + end - else + if @transport == "udp" @mcastaddr1 = Convert.to_string( SCR.Read(path(".openais.totem.interface.interface0.mcastaddr")) ) @@ -321,28 +323,34 @@ SCR.Write(path(".openais.totem.transport"), @transport) SCR.Write(path(".openais.totem.cluster_name"), @cluster_name) SCR.Write(path(".openais.totem.ip_version"), @ip_version) - if @expected_votes != "" - SCR.Write(path(".openais.quorum.expected_votes"), @expected_votes) - end + SCR.Write(path(".openais.quorum.expected_votes"), @expected_votes) # BNC#871970, only write member address when interface0 - if @transport == "udpu" + if @memberaddr != [] SCR.Write( path(".openais.nodelist.node"), generateMemberString(@memberaddr) ) - SCR.Write(path(".openais.totem.interface.interface0.mcastaddr"), "") else + SCR.Write(path(".openais.nodelist.node"), "") + end + if @transport == "udp" SCR.Write( path(".openais.totem.interface.interface0.mcastaddr"), @mcastaddr1 ) - SCR.Write(path(".openais.nodelist.node"), "") + SCR.Write( + path(".openais.totem.interface.interface0.bindnetaddr"), + @bindnetaddr1 + ) + else + SCR.Write(path(".openais.totem.interface.interface0.mcastaddr"), "") + SCR.Write(path(".openais.totem.interface.interface0.bindnetaddr"), "") end # BNC#883235. Enable "two_node" when using two node cluster - if (@expected_votes == "2") or (@transport == "udpu" && @memberaddr.size == 2) + if ((@expected_votes == "2") or (@memberaddr.size == 2)) and (!@corosync_qdevice) # Set "1" to enable two_node mode when two nodes, otherwise is "0". @two_node = "1" end @@ -354,10 +362,6 @@ SCR.Write(path(".openais.quorum.two_node"), @two_node) SCR.Write( - path(".openais.totem.interface.interface0.bindnetaddr"), - @bindnetaddr1 - ) - SCR.Write( path(".openais.totem.interface.interface0.mcastport"), @mcastport1 ) @@ -490,7 +494,8 @@ "csync2", "conntrack-tools", "hawk2", - "crmsh" + "crmsh", + "corosync-qdevice" ] ret = PackageSystem.CheckAndInstallPackagesInteractive(required_pack_list) if ret == false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-cluster-4.2.4/src/servers_non_y2/ag_openais new/yast2-cluster-4.2.5/src/servers_non_y2/ag_openais --- old/yast2-cluster-4.2.4/src/servers_non_y2/ag_openais 2019-09-27 14:29:06.000000000 +0200 +++ new/yast2-cluster-4.2.5/src/servers_non_y2/ag_openais 2019-10-16 05:12:19.000000000 +0200 @@ -65,9 +65,6 @@ "rrp_mode":{"doc":"The mode for redundant ring. None is used when only 1 interface specified, otherwise, only active or passive may be choosen", "type":"select[none,active,passive]", "default_value":"none"}, "netmtu":{"doc":"Size of MTU", "type":"int", "default_value":1500}, - "vsftype":{"doc":"The virtual synchrony filter type used to indentify a primary component. Change with care.", - "default_value":"ykd", - "suggested_value":"none"}, "token":{"doc":"Timeout for a token lost. in ms", "type":"int", "default_value":1000, "suggested_value":5000}, @@ -170,7 +167,7 @@ "model":{"doc":"Specifies the model to be used, currently only (net) is supported.","type":"string","default_value":"net","suggested_value":"net"}, "timeout":{"doc":"Specifies how often corosync-qdevice should call the votequorum_poll function.","type":"int","default_value":10000,"suggested_value":10000}, "sync_timeout":{"doc":"Specifies how often corosync-qdevice should call the votequorum_poll function during a sync phase.","type":"int","default_value":30000,"suggested_value":30000}, - "votes":{"doc":"The number of votes provided to the cluster by qdevice. Default is sum(votes_per_node) - 1.","type":"int","default_value":0} + "votes":{"doc":"The number of votes provided to the cluster by qdevice. Default is sum(votes_per_node) - 1.","type":"int","default_value":1} } quorum_qdevice_net_option_table = { @@ -270,8 +267,9 @@ f.write("\t\t%s:\t%s\n\n" % (l, quorum_qdevice_options[l])) f.write("\t}\n") else: - f.write("\t#%s\n" % (quorum_option_table[key]["doc"])) - f.write("\t%s:\t%s\n\n" % (key, quorum_options[key])) + if quorum_options[key] != "": + f.write("\t#%s\n" % (quorum_option_table[key]["doc"])) + f.write("\t%s:\t%s\n\n" % (key, quorum_options[key])) f.write("}\n") def print_qb_options(f): @@ -314,7 +312,7 @@ for log in logging_options["logger_subsys"]: f.write("\tlogger_subsys {\n") for l in log.keys(): - f.write("\t\t#%s\n\n" % (logger_subsys_option_table[l]["doc"])) + f.write("\t\t#%s\n" % (logger_subsys_option_table[l]["doc"])) f.write("\t\t%s:\t%s\n\n" % (l, log[l])) f.write("\t}\n") else:
