Hello community,

here is the log from the commit of package yast2-cluster for openSUSE:Factory 
checked in at 2014-07-04 17:18:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-cluster (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-cluster.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-cluster"

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-cluster/yast2-cluster.changes      
2014-03-12 19:09:06.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.yast2-cluster.new/yast2-cluster.changes 
2014-07-04 17:18:51.000000000 +0200
@@ -1,0 +2,76 @@
+Tue Jul  1 06:53:46 UTC 2014 - nw...@suse.com
+
+- BNC#883228 and BNC#885113. Fix various issues with YaST
+  Cluster help and the finish progress message.
+- Version 3.1.10
+
+-------------------------------------------------------------------
+Sun Jun 22 07:08:43 UTC 2014 - nw...@suse.com
+
+- BNC#883235. Auot enable "two_node" when using two node cluster.
+- Version 3.1.9
+
+-------------------------------------------------------------------
+Fri May 30 13:39:43 UTC 2014 - nw...@suse.com
+
+- BNC#879596. Detect corosync.conf format. Notice user when using
+  old format configuration.
+- Version 3.1.8
+
+-------------------------------------------------------------------
+Fri May 30 06:12:00 UTC 2014 - nw...@suse.com
+
+- BNC#880491. Check nodeid behavior when auto node id is disabled.
+  NodeID must be unique positive interger.
+- Version 3.1.7
+
+-------------------------------------------------------------------
+Thu May 29 08:57:49 UTC 2014 - nw...@suse.com
+
+- BNC#880483. Click edit button when member list is empty
+  will crash the application.
+
+-------------------------------------------------------------------
+Thu May 29 05:31:12 UTC 2014 - nw...@suse.com
+
+- BNC#880242. expected votes must have value when Transport 
+  protocol is using udp. Cluster name should not empty in 
+  any cases.
+- Version 3.1.6
+
+-------------------------------------------------------------------
+Thu May 22 09:45:56 UTC 2014 - nw...@suse.com
+
+- Modify SPEC file to make ibs and github same. Version 3.1.5 
+
+-------------------------------------------------------------------
+Wed May 21 06:49:25 UTC 2014 - nw...@suse.com
+
+- BNC#878073. Stating to run "journalctl -xn" manually for log.
+  Update version to 3.1.2 to trigger ibs/obs release.
+
+-------------------------------------------------------------------
+Wed Apr 23 07:41:49 UTC 2014 - nw...@suse.com
+
+- BNC#874710, Only active or passive of rrp_mode is valid 
+  for multiple interface.
+
+-------------------------------------------------------------------
+Tue Apr 22 08:13:18 UTC 2014 - nw...@suse.com
+
+- BNC#874563,stop pacemaker could stop corosync at the same time.
+  So change behavior to stop pacemaker directly. 
+
+-------------------------------------------------------------------
+Tue Apr 22 03:13:23 UTC 2014 - nw...@suse.com
+
+- BNC#871970.BNC#872000 could be fixed at the same time. 
+  Change udpu member addresses structure and the format of 
+  nodelist in "corosync.conf". 
+
+-------------------------------------------------------------------
+Mon Mar 10 10:12:18 UTC 2014 - dmzh...@suse.com
+
+- bnc#867090, fix expected_votes showing "nil" in case of ncurse
+
+-------------------------------------------------------------------

Old:
----
  yast2-cluster-3.1.1.tar.bz2

New:
----
  yast2-cluster-3.1.10.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-cluster.spec ++++++
--- /var/tmp/diff_new_pack.umwNGM/_old  2014-07-04 17:18:52.000000000 +0200
+++ /var/tmp/diff_new_pack.umwNGM/_new  2014-07-04 17:18:52.000000000 +0200
@@ -16,27 +16,29 @@
 #
 
 
-
 Name:           yast2-cluster
 %define _fwdefdir /etc/sysconfig/SuSEfirewall2.d/services
-Version:        3.1.1
+Version:        3.1.10
 Release:        0
-License:        GPL-2.0
-Group:          System/YaST
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 Source0:        %{name}-%{version}.tar.bz2
 Source1:        cluster.fwd
 
-Requires:       yast2
-BuildRequires:  perl-XML-Writer update-desktop-files yast2 yast2-testsuite
+BuildRequires:  perl-XML-Writer
+BuildRequires:  update-desktop-files
+BuildRequires:  yast2
 BuildRequires:  yast2-devtools >= 3.1.10
+BuildRequires:  yast2-testsuite
 
 BuildArch:      noarch
 
+Requires:       yast2
 Requires:       yast2-ruby-bindings >= 1.0.0
 
 Summary:        Configuration of cluster
+License:        GPL-2.0
+Group:          System/YaST
 
 %description
 -

++++++ yast2-cluster-3.1.1.tar.bz2 -> yast2-cluster-3.1.10.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-cluster-3.1.1/MAINTAINER 
new/yast2-cluster-3.1.10/MAINTAINER
--- old/yast2-cluster-3.1.1/MAINTAINER  2014-02-21 08:42:34.000000000 +0100
+++ new/yast2-cluster-3.1.10/MAINTAINER 2014-07-02 11:24:50.000000000 +0200
@@ -1 +1 @@
-dmzhang <dmzh...@suse.com>
+Nick Wang <nw...@suse.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-cluster-3.1.1/package/yast2-cluster.changes 
new/yast2-cluster-3.1.10/package/yast2-cluster.changes
--- old/yast2-cluster-3.1.1/package/yast2-cluster.changes       2014-02-27 
10:24:58.000000000 +0100
+++ new/yast2-cluster-3.1.10/package/yast2-cluster.changes      2014-07-02 
11:24:50.000000000 +0200
@@ -1,4 +1,80 @@
 -------------------------------------------------------------------
+Tue Jul  1 06:53:46 UTC 2014 - nw...@suse.com
+
+- BNC#883228 and BNC#885113. Fix various issues with YaST
+  Cluster help and the finish progress message.
+- Version 3.1.10
+
+-------------------------------------------------------------------
+Sun Jun 22 07:08:43 UTC 2014 - nw...@suse.com
+
+- BNC#883235. Auot enable "two_node" when using two node cluster.
+- Version 3.1.9
+
+-------------------------------------------------------------------
+Fri May 30 13:39:43 UTC 2014 - nw...@suse.com
+
+- BNC#879596. Detect corosync.conf format. Notice user when using
+  old format configuration.
+- Version 3.1.8
+
+-------------------------------------------------------------------
+Fri May 30 06:12:00 UTC 2014 - nw...@suse.com
+
+- BNC#880491. Check nodeid behavior when auto node id is disabled.
+  NodeID must be unique positive interger.
+- Version 3.1.7
+
+-------------------------------------------------------------------
+Thu May 29 08:57:49 UTC 2014 - nw...@suse.com
+
+- BNC#880483. Click edit button when member list is empty
+  will crash the application.
+
+-------------------------------------------------------------------
+Thu May 29 05:31:12 UTC 2014 - nw...@suse.com
+
+- BNC#880242. expected votes must have value when Transport 
+  protocol is using udp. Cluster name should not empty in 
+  any cases.
+- Version 3.1.6
+
+-------------------------------------------------------------------
+Thu May 22 09:45:56 UTC 2014 - nw...@suse.com
+
+- Modify SPEC file to make ibs and github same. Version 3.1.5 
+
+-------------------------------------------------------------------
+Wed May 21 06:49:25 UTC 2014 - nw...@suse.com
+
+- BNC#878073. Stating to run "journalctl -xn" manually for log.
+  Update version to 3.1.2 to trigger ibs/obs release.
+
+-------------------------------------------------------------------
+Wed Apr 23 07:41:49 UTC 2014 - nw...@suse.com
+
+- BNC#874710, Only active or passive of rrp_mode is valid 
+  for multiple interface.
+
+-------------------------------------------------------------------
+Tue Apr 22 08:13:18 UTC 2014 - nw...@suse.com
+
+- BNC#874563,stop pacemaker could stop corosync at the same time.
+  So change behavior to stop pacemaker directly. 
+
+-------------------------------------------------------------------
+Tue Apr 22 03:13:23 UTC 2014 - nw...@suse.com
+
+- BNC#871970.BNC#872000 could be fixed at the same time. 
+  Change udpu member addresses structure and the format of 
+  nodelist in "corosync.conf". 
+
+-------------------------------------------------------------------
+Mon Mar 10 10:12:18 UTC 2014 - dmzh...@suse.com
+
+- bnc#867090, fix expected_votes showing "nil" in case of ncurse
+
+-------------------------------------------------------------------
 Thu Feb 27 09:26:09 UTC 2014 - dmzh...@suse.com
 
 - upstream does not maintain yast2-python-bindings any more
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-cluster-3.1.1/package/yast2-cluster.spec 
new/yast2-cluster-3.1.10/package/yast2-cluster.spec
--- old/yast2-cluster-3.1.1/package/yast2-cluster.spec  2014-02-27 
10:24:58.000000000 +0100
+++ new/yast2-cluster-3.1.10/package/yast2-cluster.spec 2014-07-02 
11:24:50.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package yast2-cluster
 #
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,24 +18,27 @@
 
 Name:           yast2-cluster
 %define _fwdefdir /etc/sysconfig/SuSEfirewall2.d/services
-Version:        3.1.1
+Version:        3.1.10
 Release:        0
-License:       GPL-2.0
-Group:         System/YaST
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 Source0:        %{name}-%{version}.tar.bz2
 Source1:        cluster.fwd
 
-Requires:      yast2
-BuildRequires: perl-XML-Writer update-desktop-files yast2 yast2-testsuite
+BuildRequires:  perl-XML-Writer
+BuildRequires:  update-desktop-files
+BuildRequires:  yast2
 BuildRequires:  yast2-devtools >= 3.1.10
+BuildRequires:  yast2-testsuite
 
-BuildArchitectures:    noarch
+BuildArch:      noarch
 
+Requires:       yast2
 Requires:       yast2-ruby-bindings >= 1.0.0
 
-Summary:       Configuration of cluster
+Summary:        Configuration of cluster
+License:        GPL-2.0
+Group:          System/YaST
 
 %description
 -
@@ -52,8 +55,6 @@
 mkdir -p $RPM_BUILD_ROOT/%{_fwdefdir}
 install -m 644 %{S:1} $RPM_BUILD_ROOT/%{_fwdefdir}/cluster
 
-
-
 %files
 %defattr(-,root,root)
 %dir %{yast_yncludedir}/cluster
@@ -66,3 +67,5 @@
 %{yast_agentdir}/ag_openais
 %doc %{yast_docdir}
 %config %{_fwdefdir}/cluster
+
+%changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-cluster-3.1.1/src/include/cluster/dialogs.rb 
new/yast2-cluster-3.1.10/src/include/cluster/dialogs.rb
--- old/yast2-cluster-3.1.1/src/include/cluster/dialogs.rb      2014-02-25 
10:14:04.000000000 +0100
+++ new/yast2-cluster-3.1.10/src/include/cluster/dialogs.rb     2014-07-02 
11:24:50.000000000 +0200
@@ -1,4 +1,4 @@
-# encoding: utf-8
+#encoding: utf-8
 
 # 
------------------------------------------------------------------------------
 # Copyright (c) 2006 Novell, Inc. All Rights Reserved.
@@ -25,6 +25,8 @@
 # Authors:     Cong Meng <cm...@novell.com>
 #
 # $Id: wizards.ycp 27914 2006-02-13 14:32:08Z locilka $
+require 'set'
+
 module Yast
   module ClusterDialogsInclude
     def initialize_cluster_dialogs(include_target)
@@ -67,7 +69,7 @@
       @usable_interface = []
     end
 
-    # return `cacel or a string
+    # return `cancel or a string
     def text_input_dialog(title, value)
       ret = nil
 
@@ -94,20 +96,23 @@
       deep_copy(ret)
     end
 
-    def addr_input_dialog(value, autoid)
+    def addr_input_dialog(value, autoid, dual)
       ret = nil
 
       value.default=""
-
+ 
+      # BNC#871970, change member address struct
       UI.OpenDialog(
         MarginBox(
           1,
           1,
           VBox(
             HBox(
-            MinWidth(75, InputField(Id(:addr), _("IP Address"), value[:addr])),
+            MinWidth(40, InputField(Id(:addr1), _("IP Address"), 
value[:addr1])),
+            HSpacing(1),
+            MinWidth(40, InputField(Id(:addr2), _("Redundant IP Address"), 
value[:addr2])),
             HSpacing(1),
-            MinWidth(25, InputField(Id(:mynodeid), _("nodeid") , 
value[:nodeid]))
+            MinWidth(20, InputField(Id(:mynodeid), _("nodeid") , 
value[:nodeid]))
             ),
             VSpacing(1),
             Right(
@@ -120,25 +125,66 @@
         )
       )
 
-
-
       if (autoid)
         UI.ChangeWidget(:mynodeid, :Enabled, false)
       end
 
+      if (!dual)
+        UI.ChangeWidget(:addr2, :Enabled, false)
+      end
+
       ret = UI.UserInput
       if ret == :ok
-        if UI.QueryWidget(:mynodeid, :Value) != ""
-          ret = {:addr=>UI.QueryWidget(:addr, :Value), 
:nodeid=>UI.QueryWidget(:mynodeid, :Value)}
+        if ( UI.QueryWidget(:mynodeid, :Value) != "" ) && ( 
UI.QueryWidget(:addr2, :Value) != "" )
+          ret = {:addr1 => UI.QueryWidget(:addr1, :Value), :addr2 => 
UI.QueryWidget(:addr2, :Value), :nodeid => UI.QueryWidget(:mynodeid, :Value)}
+        elsif ( UI.QueryWidget(:mynodeid, :Value) == "" ) && ( 
UI.QueryWidget(:addr2, :Value) != "" )
+          ret = {:addr1 => UI.QueryWidget(:addr1, :Value), :addr2 => 
UI.QueryWidget(:addr2, :Value)}
+        elsif ( UI.QueryWidget(:mynodeid, :Value) != "" ) && ( 
UI.QueryWidget(:addr2, :Value) == "" )
+          ret = {:addr1 => UI.QueryWidget(:addr1, :Value), :nodeid => 
UI.QueryWidget(:mynodeid, :Value)}
         else
-          ret = {:addr=>UI.QueryWidget(:addr, :Value)}
+          ret = {:addr1 => UI.QueryWidget(:addr1, :Value)}
         end
       end
       UI.CloseDialog
       deep_copy(ret)
     end
 
+    def ValidNodeID
+      if Cluster.memberaddr.size <= 0
+         return true
+      end
+
+      i = 0
+      # Set need to require 'set'
+      idset = Set[]
 
+      Builtins.foreach(Cluster.memberaddr) do |value|
+        if  value[:nodeid].to_i <= 0
+          Popup.Message("Node ID has to be fulfilled with a positive integer")
+          UI.ChangeWidget(:memberaddr, :CurrentItem, i)
+          i = 0
+          raise Break
+        end
+
+        if idset.include?(value[:nodeid].to_i)
+          Popup.Message("Node ID must be unique")
+          UI.ChangeWidget(:memberaddr, :CurrentItem, i)
+          i = 0
+          raise Break
+        end
+
+        idset << value[:nodeid].to_i
+        i = Ops.add(i, 1)
+      end
+
+      if i == 0
+        return false
+      end
+
+      true
+    end
+ 
+    # BNC#871970, change member address struct
     def ValidateCommunication
       i = 0
       if IP.Check(Convert.to_string(UI.QueryWidget(Id(:bindnetaddr1), 
:Value))) == false
@@ -147,23 +193,36 @@
         return false
       end
 
+      if UI.QueryWidget(Id(:cluster_name), :Value) == ""
+        Popup.Message("The cluster name has to be fulfilled")
+        UI.SetFocus(:cluster_name)
+        return false
+      end
+
       if UI.QueryWidget(Id(:transport), :Value) == "udpu"
         i = 0
-        Builtins.foreach(Cluster.memberaddr1) do |value|
-          if IP.Check(value[:addr]) == false
-            UI.ChangeWidget(:memberaddr1, :CurrentItem, i)
+        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(:memberaddr1)
+          UI.SetFocus(:memberaddr)
           Popup.Message("The Member Address has to be fulfilled")
           return false
         end
       else
-        if IP.Check(Convert.to_string(UI.QueryWidget(Id(:mcastaddr1), 
:Value))) == false
+        #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 udp is 
configured")
+          UI.SetFocus(:expected_votes)
+          return false
+        end
+
+        if !IP.Check(Convert.to_string(UI.QueryWidget(Id(:mcastaddr1), 
:Value)))
           Popup.Message("The Multicast Address has to be fulfilled")
           UI.SetFocus(:mcastaddr1)
           return false
@@ -179,7 +238,7 @@
         return false
       end
 
-      if UI.QueryWidget(Id(:enable2), :Value) == true
+      if UI.QueryWidget(Id(:enable2), :Value)
         if IP.Check(
             Convert.to_string(UI.QueryWidget(Id(:bindnetaddr2), :Value))
           ) == false
@@ -188,22 +247,7 @@
           return false
         end
 
-        if UI.QueryWidget(Id(:transport), :Value) == "udpu"
-          i = 0
-          Builtins.foreach(Cluster.memberaddr2) do |value|
-            if IP.Check(value[:addr]) == false
-              UI.ChangeWidget(:memberaddr2, :CurrentItem, i)
-              i = 0
-              raise Break
-            end
-            i = Ops.add(i, 1)
-          end
-          if i == 0
-            UI.SetFocus(:memberaddr2)
-            Popup.Message("The Member Address has to be fulfilled")
-            return false
-          end
-        else
+        if UI.QueryWidget(Id(:transport), :Value) == "udp"
           if IP.Check(
               Convert.to_string(UI.QueryWidget(Id(:mcastaddr2), :Value))
             ) == false
@@ -221,9 +265,22 @@
           UI.SetFocus(Id(:mcastport2))
           return false
         end
+
+        if UI.QueryWidget(Id(:rrpmode), :Value) == "none"
+          Popup.Message("Only passive or active can be chosen if multiple 
interface used. Set to passive.")
+          UI.ChangeWidget(Id(:rrpmode), :Value, "passive")
+          UI.SetFocus(Id(:rrpmode))
+          return false
+        end
       end
 
-      votes = UI.QueryWidget(Id(:expected_votes), :Value)
+      if !UI.QueryWidget(Id(:autoid), :Value ) && ( 
UI.QueryWidget(Id(:transport), :Value) == "udpu" )
+        ret = ValidNodeID()
+        if !ret
+           UI.SetFocus(Id(:memberaddr))
+           return false
+        end
+      end
 
       true
     end
@@ -242,7 +299,7 @@
         Convert.to_string(UI.QueryWidget(Id(:mcastport1), :Value))
       )
 
-      if UI.QueryWidget(Id(:enable2), :Value) == false
+      if !UI.QueryWidget(Id(:enable2), :Value)
         SCR.Write(path(".openais.totem.interface.interface1"), "")
       else
         SCR.Write(
@@ -259,7 +316,7 @@
         )
       end
 
-      if UI.QueryWidget(Id(:autoid), :Value) == true
+      if UI.QueryWidget(Id(:autoid), :Value)
         SCR.Write(path(".openais.totem.autoid"), "yes")
       else
         SCR.Write(path(".openais.totem.autoid"), "no")
@@ -301,6 +358,15 @@
         UI.QueryWidget(Id(:transport), :Value)
       )
 
+      #BNC#871970, clear second IP when redundant channel is disabled
+      if !UI.QueryWidget(Id(:enable2), :Value)
+        Cluster.memberaddr.each { |member| member[:addr2] = "" }
+      end
+
+      if UI.QueryWidget(Id(:autoid), :Value)
+        Cluster.memberaddr.each  { |member| member[:nodeid] = "" }
+      end
+
       nil
     end
 
@@ -315,29 +381,27 @@
     end
 
 
+    # BNC#871970, change member address struct to memberaddr
     def transport_switch
-      udp = Convert.to_string(UI.QueryWidget(Id(:transport), :Value)) == "udp"
-      enable2 = Convert.to_boolean(UI.QueryWidget(Id(:enable2), :Value))
+      udp = UI.QueryWidget(Id(:transport), :Value) == "udp"
+      enable2 = UI.QueryWidget(Id(:enable2), :Value)
 
       enable1 = udp
       enable2 = udp && enable2
 
       UI.ChangeWidget(Id(:mcastaddr1), :Enabled, enable1)
-      UI.ChangeWidget(Id(:memberaddr1), :Enabled, !enable1)
-      UI.ChangeWidget(Id(:memberaddr1_add), :Enabled, !enable1)
-      UI.ChangeWidget(Id(:memberaddr1_del), :Enabled, !enable1)
-      UI.ChangeWidget(Id(:memberaddr1_edit), :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(:memberaddr2), :Enabled, !enable2)
-      UI.ChangeWidget(Id(:memberaddr2_add), :Enabled, !enable2)
-      UI.ChangeWidget(Id(:memberaddr2_del), :Enabled, !enable2)
-      UI.ChangeWidget(Id(:memberaddr2_edit), :Enabled, !enable2)
 
       nil
     end
 
 
+    # BNC#871970, change member address struct to memberaddr
     def CommunicationLayout
       result = {}
 
@@ -391,13 +455,6 @@
             _("Multicast Address:")
           ),
           InputField(Id(:mcastport1), Opt(:hstretch), _("Multicast Port:")),
-          Left(Label(_("Member Address:"))),
-          Table(Id(:memberaddr1), Header("ip","nodeid"),[]),
-          HBox(
-            PushButton(Id(:memberaddr1_add), "Add"),
-            PushButton(Id(:memberaddr1_del), "Del"),
-            PushButton(Id(:memberaddr1_edit), "Edit")
-          )
         )
       )
 
@@ -415,38 +472,39 @@
           ),
           InputField(Id(:mcastaddr2), Opt(:hstretch), _("Multicast Address:")),
           InputField(Id(:mcastport2), Opt(:hstretch), _("Multicast Port:")),
-          Left(Label(_("Member Address:"))),
-          Table(Id(:memberaddr2), Header("ip","nodeid"),[]),
-          HBox(
-            PushButton(Id(:memberaddr2_add), "Add"),
-            PushButton(Id(:memberaddr2_del), "Del"),
-            PushButton(Id(:memberaddr2_edit), "Edit")
-          )
         )
       )
 
       nid = VBox(
         HBox(
           Left(InputField(Id(:cluster_name),Opt(:hstretch), _("Cluster 
Name:"))),
-          Left(InputField(Id(:expected_votes),Opt(:hstretch), _("expected 
votes:"),"")),
+          Left(InputField(Id(:expected_votes),Opt(:hstretch), _("Expected 
Votes:"),"")),
+          ComboBox(
+            Id(:rrpmode),
+            Opt(:hstretch),
+            _("rrp mode:"),
+            ["none", "active", "passive"]
+          )
         ),
         Left(
           CheckBox(Id(:autoid), Opt(:notify), _("Auto Generate Node ID"), true)
         )
       )
 
-      rrpm = VBox(
-        ComboBox(
-          Id(:rrpmode),
-          Opt(:hstretch),
-          _("rrp mode:"),
-          ["none", "active", "passive"]
+      ip_table = VBox(
+        Left(Label(_("Member Address:"))),
+        Table(Id(:memberaddr), Header("IP", "Redundant IP", "nodeid"), []),
+        Right(HBox(
+          PushButton(Id(:memberaddr_add), "Add"),
+          PushButton(Id(:memberaddr_del), "Del"),
+          PushButton(Id(:memberaddr_edit), "Edit"))
         ))
 
-
       contents = VBox(
         transport,
-        HBox(HWeight(1,VBox(iface, nid)),HWeight(1,VBox(riface, rrpm)))
+        HBox(HWeight(1, VBox(iface)), HWeight(1, VBox(riface))),
+        ip_table,
+        HBox(nid),
       )
 
       my_SetContents("communication", contents)
@@ -473,6 +531,12 @@
         UI.ChangeWidget(Id(:rrpmode), :Enabled, true)
       end
 
+      # BNC#879596, check the corosync.conf format
+      if Cluster.config_format == "old"
+        Popup.Message(" NOTICE: Detected old corosync configuration.\n Please 
reconfigure the member list and confirm all other settings.")
+        Cluster.config_format = "showed"
+      end
+
       transport_switch
 
       nil
@@ -485,34 +549,22 @@
       current = 0
       items = []
 
+      # BNC#871970,change structure
       # remove duplicated elements
-      Cluster.memberaddr1 = Ops.add(Cluster.memberaddr1, [])
-      Cluster.memberaddr2 = Ops.add(Cluster.memberaddr2, [])
+      Cluster.memberaddr = Ops.add(Cluster.memberaddr, [])
 
       i = 0
       items = []
-      Builtins.foreach(Cluster.memberaddr1) do |value|
-          items.push(Item(Id(i), value[:addr], value[:nodeid]))
+      Builtins.foreach(Cluster.memberaddr) do |value|
+          items.push(Item(Id(i), value[:addr1],value[:addr2], value[:nodeid]))
           i += 1
       end
 
-      current = Convert.to_integer(UI.QueryWidget(:memberaddr1, :CurrentItem))
+      current = Convert.to_integer(UI.QueryWidget(:memberaddr, :CurrentItem))
       current = 0 if current == nil
       current = Ops.subtract(i, 1) if Ops.greater_or_equal(current, i)
-      UI.ChangeWidget(:memberaddr1, :Items, items)
-      UI.ChangeWidget(:memberaddr1, :CurrentItem, current)
-
-      i = 0
-      items = []
-      Builtins.foreach(Cluster.memberaddr2) do |value|
-        items.push(Item(Id(i), value[:addr], value[:nodeid]))
-        i += 1
-      end
-      current = Convert.to_integer(UI.QueryWidget(:memberaddr2, :CurrentItem))
-      current = 0 if current == nil
-      current = Ops.subtract(i, 1) if Ops.greater_or_equal(current, i)
-      UI.ChangeWidget(:memberaddr2, :Items, items)
-      UI.ChangeWidget(:memberaddr2, :CurrentItem, current)
+      UI.ChangeWidget(:memberaddr, :Items, items)
+      UI.ChangeWidget(:memberaddr, :CurrentItem, current)
 
       nil
     end
@@ -544,66 +596,44 @@
         end
 
         if ret == :enable2
-          if true == UI.QueryWidget(Id(:enable2), :Value)
+          if UI.QueryWidget(Id(:enable2), :Value)
+            # Changewidget items will change value to first one automatically
+            rrpvalue = UI.QueryWidget(Id(:rrpmode), :Value)
+            UI.ChangeWidget(Id(:rrpmode), :Items, ["passive","active"])
             UI.ChangeWidget(Id(:rrpmode), :Enabled, true)
-            UI.ChangeWidget(Id(:rrpmode), :Value, "passive")
+            UI.ChangeWidget(Id(:rrpmode), :Value, rrpvalue) if rrpvalue != 
"none"
           else
+            UI.ChangeWidget(Id(:rrpmode), :Items, ["none"])
             UI.ChangeWidget(Id(:rrpmode), :Value, "none")
             UI.ChangeWidget(Id(:rrpmode), :Enabled, false)
           end
         end
 
-        if ret == :memberaddr1_add
-          ret = addr_input_dialog({}, UI.QueryWidget(Id(:autoid), :Value))
+        if ret == :memberaddr_add
+          ret = addr_input_dialog({}, UI.QueryWidget(Id(:autoid), :Value), 
UI.QueryWidget(Id(:enable2), :Value))
           next if ret == :cancel
-          Cluster.memberaddr1.push(ret)
+          Cluster.memberaddr.push(ret)
         end
 
-        if ret == :memberaddr1_edit
+        if ret == :memberaddr_edit
           current = 0
           str = ""
 
-          current = Convert.to_integer(
-            UI.QueryWidget(:memberaddr1, :CurrentItem)
-          )
-          ret = addr_input_dialog(Cluster.memberaddr1[current] || "" 
,UI.QueryWidget(Id(:autoid), :Value))
-          next if ret == :cancel
-          Cluster.memberaddr1[current]= ret
-        end
-
-        if ret == :memberaddr1_del
-          current = 0
-          current = Convert.to_integer(
-            UI.QueryWidget(:memberaddr1, :CurrentItem)
-          )
-          Cluster.memberaddr1 = Builtins.remove(Cluster.memberaddr1, current)
-        end
-
-        if ret == :memberaddr2_add
-          ret = addr_input_dialog({}, UI.QueryWidget(Id(:autoid), :Value))
-          next if ret == :cancel
-          Cluster.memberaddr2.push(ret)
-        end
+          # The value will be nil if the list is empty, however nil.to_i is 0
+          current = UI.QueryWidget(:memberaddr, :CurrentItem).to_i
 
-        if ret == :memberaddr2_edit
-          current = 0
-          str = ""
-
-          current = Convert.to_integer(
-            UI.QueryWidget(:memberaddr2, :CurrentItem)
-          )
-          ret = addr_input_dialog(Cluster.memberaddr2[current] || "" ,
-                                  UI.QueryWidget(Id(:autoid), :Value))
+          ret = addr_input_dialog(Cluster.memberaddr[current] || {} 
,UI.QueryWidget(Id(:autoid), :Value ), UI.QueryWidget(Id(:enable2), :Value))
           next if ret == :cancel
-          Cluster.memberaddr1[current] = ret
+          Cluster.memberaddr[current]= ret
         end
 
-        if ret == :memberaddr2_del
+        if ret == :memberaddr_del
           current = 0
           current = Convert.to_integer(
-            UI.QueryWidget(:memberaddr2, :CurrentItem)
+            UI.QueryWidget(:memberaddr, :CurrentItem)
           )
-          Cluster.memberaddr2 = Builtins.remove(Cluster.memberaddr2, current)
+          # Notice, current could be "nil" if the list is empty.
+          Cluster.memberaddr = Builtins.remove(Cluster.memberaddr, current)
         end
 
         if ret == :next || ret == :back
@@ -705,7 +735,7 @@
             VSpacing(1),
             Label(
               _(
-                "For newly created cluster, push the button below to generate 
/etc/corosync/authkey."
+                "For a newly created cluster, push the button below to 
generate /etc/corosync/authkey."
               )
             ),
             Label(
@@ -909,6 +939,7 @@
       my_SetContents("service", contents)
 
       event = {}
+      errormsg = "See 'journalctl -xn' for details."
       CWMFirewallInterfaces.OpenFirewallInit(firewall_widget, "")
       while true
         UpdateServiceStatus()
@@ -927,16 +958,18 @@
         end
 
         # pacemaker will start corosync automatically.
-        # to stop pacemaker, you have to stop corosync first.
+        # BNC#872651 is fixed, so stop pacemaker could stop corosync at the 
same time.
         if ret == "start_now"
           Cluster.save_csync2_conf
           Cluster.SaveClusterConfig
-          Report.Error(Service.Error) if !Service.Start("pacemaker")
+          # BNC#872651 , add more info about error message
+          Report.Error(Service.Error + errormsg) if !Service.Start("pacemaker")
           next
         end
 
         if ret == "stop_now"
-          Report.Error(Service.Error) if !Service.Stop("corosync")
+          # BNC#874563,stop pacemaker could stop corosync since BNC#872651 is 
fixed
+          Report.Error(Service.Error + errormsg) if !Service.Stop("pacemaker")
           next
         end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-cluster-3.1.1/src/include/cluster/helps.rb 
new/yast2-cluster-3.1.10/src/include/cluster/helps.rb
--- old/yast2-cluster-3.1.1/src/include/cluster/helps.rb        2014-02-21 
08:42:34.000000000 +0100
+++ new/yast2-cluster-3.1.10/src/include/cluster/helps.rb       2014-07-02 
11:24:50.000000000 +0200
@@ -38,7 +38,9 @@
             "<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" +
             "<p><b><big>Member Address</big></b><br>This list specifies all 
the nodes in the cluster by IP address. This could be configurable when using 
udpu <br></p>\n" +
             "<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>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>Expected votes</big></b><br>Expect vote number for 
voting quorum.  Will be automatically calculated when the nodelist {} section 
is present in corosync.conf or can be specified in the quorum {} 
section.<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"
         ),
         "security"      => _(
           "\n" +
@@ -47,7 +49,8 @@
         ),
         "service"       => _(
           "\n" +
-            "\t\t\t<p><b><big>Booting</big></b><br>Starting openais service 
during boot or not</p>\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>Firewall Settings</big></b><br>Enable the port 
when Firewall is enabled</p>\n" +
             "\t\t\t"
         ),
         "csync2"        => _(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-cluster-3.1.1/src/include/cluster/wizards.rb 
new/yast2-cluster-3.1.10/src/include/cluster/wizards.rb
--- old/yast2-cluster-3.1.1/src/include/cluster/wizards.rb      2014-02-21 
08:42:34.000000000 +0100
+++ new/yast2-cluster-3.1.10/src/include/cluster/wizards.rb     2014-07-02 
11:24:50.000000000 +0200
@@ -87,8 +87,8 @@
       else
         UI.WizardCommand(term(:SetNextButtonLabel, Label.FinishButton))
         UI.WizardCommand(term(:SetAbortButtonLabel, Label.CancelButton))
-        Wizard.HideBackButton
       end
+      Wizard.HideBackButton
 
       Wizard.SelectTreeItem(Ops.get_string(sequence, "ws_start", ""))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-cluster-3.1.1/src/modules/Cluster.rb 
new/yast2-cluster-3.1.10/src/modules/Cluster.rb
--- old/yast2-cluster-3.1.1/src/modules/Cluster.rb      2014-02-21 
08:42:34.000000000 +0100
+++ new/yast2-cluster-3.1.10/src/modules/Cluster.rb     2014-07-02 
11:24:50.000000000 +0200
@@ -69,6 +69,8 @@
       @threads = ""
       @cluster_name = ""
       @expected_votes = ""
+      @two_node = ""
+      @config_format = ""
 
       @bindnetaddr1 = ""
       @mcastaddr1 = ""
@@ -89,10 +91,12 @@
       @transport = ""
 
       # example:
-      # [{:addr=>"10.16.35.101", :nodeid=>"1"}, {:addr=>"10.16.35.102", 
:nodeid=>"2"},
-      # {:addr=>"10.16.35.103"}, {:addr=>"10.16.35.104"}, 
{:addr=>"10.16.35.105"}]
-      @memberaddr1 = []
-      @memberaddr2 = []
+      # [{:addr1=>"10.16.35.101",:addr2=>"192.168.0.1", :nodeid=>"1"}, 
+      # {:addr1=>"10.16.35.102",:addr2=>"192.168.0.2", :nodeid=>"2"},
+      # {:addr1=>"10.16.35.103",:addr2=>"192.168.0.3" },
+      # {:addr1=>"10.16.35.104",:nodeid=>"4" },
+      # {:addr1=>"10.16.35.105",:nodeid=>"5" }]
+      @memberaddr = []
 
       @csync2_host = []
       @csync2_include = []
@@ -163,6 +167,7 @@
 
       @expected_votes = SCR.Read(path(".openais.quorum.expected_votes")).to_s
 
+      @config_format = 
SCR.Read(path(".openais.totem.interface.member.memberaddr")).to_s
 
       @transport = SCR.Read(path(".openais.totem.transport"))
       @transport = "udp" if @transport == nil
@@ -171,15 +176,29 @@
       Builtins.foreach(interfaces) do |interface|
         if interface == "interface0"
           if @transport == "udpu"
-            address = 
SCR.Read(path(".openais.totem.interface.interface0.member")).split(" ")
+            # 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|
               p = addr.split(":")
               if p[1] != nil
-                @memberaddr1.push({:addr=>p[0],:nodeid=>p[1]})
-              elsif
-                @memberaddr1.push({:addr=>p[0]})
+                q = p[0].split(";")
+                if q[1] != nil
+                  @memberaddr.push({:addr1=>q[0],:addr2=>q[1],:nodeid=>p[1]})
+                else
+                  @memberaddr.push({:addr1=>q[0],:nodeid=>p[1]})
+                end
+              else
+                q = p[0].split(";")
+                if q[1] != nil
+                  @memberaddr.push({:addr1=>q[0],:addr2=>q[1]})
+                else
+                  @memberaddr.push({:addr1=>q[0]})
+                end
               end
-            end
+            end  # end address.each 
 
           else
             @mcastaddr1 = Convert.to_string(
@@ -194,17 +213,8 @@
           )
         end
         if interface == "interface1"
-          if @transport == "udpu"
-            address = 
SCR.Read(path(".openais.totem.interface.interface1.member")).split(" ")
-            address.each do |addr|
-              p = addr.split(":")
-              if p[1] != nil
-                @memberaddr2.push({:addr=>p[0],:nodeid=>p[1]})
-              elsif
-                @memberaddr2.push({:addr=>p[0]})
-              end
-            end
-          else
+          # member address only get in interface0
+          if @transport == "udp"
             @mcastaddr2 = Convert.to_string(
               SCR.Read(path(".openais.totem.interface.interface1.mcastaddr"))
             )
@@ -239,15 +249,20 @@
     end
 
 
+    # BNC#871970, generate string like "123.3.21.32;156.32.123.1:1"
     def generateMemberString(memberaddr)
       address_string = ""
       memberaddr.each do |i|
-        address_string += i[:addr]
-        if i[:nodeid]
-          address_string += ":#{i[:nodeid]}"
+        address_string << i[:addr1]
+        if i[:addr2]
+          address_string << ";#{i[:addr2]}"
+          address_string << ":#{i[:nodeid]}" if i [:nodeid]
+        else 
+          address_string << ":#{i[:nodeid]}" if i[:nodeid]
         end
-        address_string += " "
+        address_string << " "
       end
+
       return address_string
     end
 
@@ -264,12 +279,13 @@
       SCR.Write(path(".openais.totem.transport"), @transport)
       SCR.Write(path(".openais.totem.cluster_name"), @cluster_name)
       SCR.Write(path(".openais.quorum.expected_votes"), @expected_votes)
-
+  
+      # BNC#871970, only write member address when interface0  
       if @transport == "udpu"
 
         SCR.Write(
-          path(".openais.totem.interface.interface0.member"),
-          generateMemberString(@memberaddr1)
+          path(".openais.nodelist.node"),
+          generateMemberString(@memberaddr)
         )
         SCR.Write(path(".openais.totem.interface.interface0.mcastaddr"), "")
       else
@@ -277,8 +293,16 @@
           path(".openais.totem.interface.interface0.mcastaddr"),
           @mcastaddr1
         )
-        SCR.Write(path(".openais.totem.interface.interface0.member"), "")
+        SCR.Write(path(".openais.nodelist.node"), "")
+      end
+
+      # BNC#883235. Enable "two_node" when using two node cluster
+      if (@expected_votes == "2") or (@transport == "udpu" && @memberaddr.size 
== 2)
+        # Set "1" to enable two_node mode when two nodes, otherwise is "0".
+        @two_node = "1"
       end
+      SCR.Write(path(".openais.quorum.two_node"), @two_node)
+
       SCR.Write(
         path(".openais.totem.interface.interface0.bindnetaddr"),
         @bindnetaddr1
@@ -292,17 +316,12 @@
         SCR.Write(path(".openais.totem.interface.interface1"), "")
       else
         if @transport == "udpu"
-          SCR.Write(
-            path(".openais.totem.interface.interface1.member"),
-            generateMemberString(@memberaddr2)
-          )
           SCR.Write(path(".openais.totem.interface.interface1.mcastaddr"), "")
         else
           SCR.Write(
             path(".openais.totem.interface.interface1.mcastaddr"),
             @mcastaddr2
           )
-          SCR.Write(path(".openais.totem.interface.interface1.member"), "")
         end
         SCR.Write(
           path(".openais.totem.interface.interface1.bindnetaddr"),
@@ -471,6 +490,7 @@
       Builtins.sleep(sl)
 
       return false if Abort()
+      Progress.Finish
       @modified = false
       true
     end
@@ -485,7 +505,6 @@
       steps = 2
 
       sl = 500
-      Builtins.sleep(sl)
 
       # TODO FIXME Names of real stages
       # We do not set help text here, because it was set outside
@@ -576,6 +595,8 @@
           )
         )
       end
+      # is that necessary? since enable pacemaker will trigger corosync/csync2?
+      # FIXME if not necessary
       if @global_startopenais == true
         SCR.Execute(path(".target.bash_output"), "systemctl enable 
corosync.service")
       end
@@ -584,6 +605,7 @@
       end
 
       return false if Abort()
+      Progress.Finish
       true
     end
 
@@ -591,20 +613,21 @@
     # (For use by autoinstallation.)
     # @param [Hash] settings The YCP structure to be imported.
     # @return [Boolean] True on success
+    # BNC#871970 , change to memberaddr. But seems still not functional
     def Import(settings)
       settings = deep_copy(settings)
       @secauth = Ops.get_boolean(settings, "secauth", false)
       @threads = Ops.get_string(settings, "threads", "")
       @transport = Ops.get_string(settings, "transport", "udp")
       @bindnetaddr1 = Ops.get_string(settings, "bindnetaddr1", "")
-      @memberaddr1 = Ops.get_list(settings, "memberaddr1", [])
+      @memberaddr = Ops.get_list(settings, "memberaddr", [])
       @mcastaddr1 = Ops.get_string(settings, "mcastaddr1", "")
       @cluster_name  = settings["cluster_name"] || ""
       @expected_votes = settings["expected_votes"] || ""
-      @mcastport1 = Ops.get_string(settings, "mcastport1", "")
+      @two_node = settings["two_node"] || ""
+      @mcastport2 = Ops.get_string(settings, "mcastport1", "")
       @enable2 = Ops.get_boolean(settings, "enable2", false)
       @bindnetaddr2 = Ops.get_string(settings, "bindnetaddr2", "")
-      @memberaddr2 = Ops.get_list(settings, "memberaddr2", [])
       @mcastaddr2 = Ops.get_string(settings, "mcastaddr2", "")
       @mcastport2 = Ops.get_string(settings, "mcastport2", "")
       @autoid = Ops.get_boolean(settings, "autoid", true)
@@ -623,20 +646,21 @@
     # Dump the cluster settings to a single map
     # (For use by autoinstallation.)
     # @return [Hash] Dumped settings (later acceptable by Import ())
+    # BNC#871970 , change to memberaddr. But seems still not functional
     def Export
       result = {}
       Ops.set(result, "secauth", @secauth)
       Ops.set(result, "threads", @threads)
       Ops.set(result, "transport", @transport)
       Ops.set(result, "bindnetaddr1", @bindnetaddr1)
-      Ops.set(result, "memberaddr1", @memberaddr1)
+      Ops.set(result, "memberaddr", @memberaddr)
       Ops.set(result, "mcastaddr1", @mcastaddr1)
       result["cluster_name"] = @cluster_name
       result["expected_votes"] = @expected_votes
+      result["two_node"] = @two_node
       Ops.set(result, "mcastport1", @mcastport1)
       Ops.set(result, "enable2", @enable2)
       Ops.set(result, "bindnetaddr2", @bindnetaddr2)
-      Ops.set(result, "memberaddr2", @memberaddr2)
       Ops.set(result, "mcastaddr2", @mcastaddr2)
       Ops.set(result, "mcastport2", @mcastport2)
       Ops.set(result, "autoid", true)
@@ -725,6 +749,8 @@
     publish :variable => :mcastaddr1, :type => "string"
     publish :variable => :cluster_name, :type => "string"
     publish :variable => :expected_votes, :type => "string"
+    publish :variable => :two_node, :type => "string"
+    publish :variable => :config_format, :type => "string"
     publish :variable => :mcastport1, :type => "string"
     publish :variable => :enable2, :type => "boolean"
     publish :variable => :bindnetaddr2, :type => "string"
@@ -738,8 +764,7 @@
     publish :variable => :global_startopenais, :type => "boolean"
     publish :variable => :global_startcsync2, :type => "boolean"
     publish :variable => :transport, :type => "string"
-    publish :variable => :memberaddr1, :type => "list <string>"
-    publish :variable => :memberaddr2, :type => "list <string>"
+    publish :variable => :memberaddr, :type => "list <string>"
     publish :function => :SaveClusterConfig, :type => "void ()"
     publish :variable => :csync2_host, :type => "list <string>"
     publish :variable => :csync2_include, :type => "list <string>"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-cluster-3.1.1/src/servers_non_y2/ag_openais 
new/yast2-cluster-3.1.10/src/servers_non_y2/ag_openais
--- old/yast2-cluster-3.1.1/src/servers_non_y2/ag_openais       2014-02-27 
10:24:58.000000000 +0100
+++ new/yast2-cluster-3.1.10/src/servers_non_y2/ag_openais      2014-07-02 
11:24:50.000000000 +0200
@@ -108,7 +108,7 @@
        "rrp_problem_count_threshhold":{"doc":"The number of times a problem is 
detected with a link before setting the link faulty.",
                                        "type":"int", "default_value":10},
        "rrp_token_expired_timeout":{"doc":"This specifies the time in 
milliseconds to increment the problem counter for the redundant ring protocol 
after not having received a token from all rings for a particular processor.", 
"type":"int", "default_value":47},
-       "transport":{"doc":"", "type":"select[udp,udpu]","default_value":"udp"},
+       "transport":{"doc":"Transport protocol", 
"type":"select[udp,udpu]","default_value":"udp"},
 }
 
 
@@ -130,6 +130,11 @@
                "nodeid":{"doc":"required in ipv6, optional in 
ipv4","type":"string"},
 }
 
+#BNC-879596. Obsolete, just use to detect the file format is SLE11SP3 or SLE12
+old_memberlist_table = {
+               "memberaddr":{"doc":"obsolete! Only use to detect old(SLE11SP3) 
format.", "type":"string", "default_value":"0"},
+}
+
 logging_option_table = {
        "debug":{"doc":"Whether or not turning on the debug information in the 
log", "default_value":"off",
                 "suggested_value":"off"},
@@ -210,7 +215,7 @@
                if quorum_options[key] == "":
                        continue
                else:
-                       f.write("\t#%s\n\n" % (quorum_option_table[key]["doc"]))
+                       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")
 
@@ -219,7 +224,7 @@
                return
        f.write("qb {\n");
        for key in qb_options.keys():
-               f.write("\t#%s\n\n" % (qb_option_table[key]["doc"]))
+               f.write("\t#%s\n" % (qb_option_table[key]["doc"]))
                f.write("\t%s:\t%s\n\n" % (key, qb_options[key]))
        f.write("}\n")
 
@@ -230,7 +235,12 @@
        f.write("nodelist {\n");
        for node in nodelist:
                f.write("\tnode {\n")
-               for key in node.keys():
+               # Sort the keys like ring0 and ring1
+               klist=node.keys()
+               klist.sort()
+               for key in klist:
+                       if node[key] == "":
+                               continue
                        f.write("\t#%s\n" % (node_option_table[key]["doc"]))
                        f.write("\t%s:\t%s\n\n" % (key, node[key]))
                f.write("\t}\n")
@@ -248,7 +258,7 @@
                                        f.write("\t\t%s:\t%s\n\n" % (l, log[l]))
                                f.write("\t}\n")
                        continue
-               f.write("\t#%s\n\n" % (logging_option_table[key]["doc"]))
+               f.write("\t#%s\n" % (logging_option_table[key]["doc"]))
                f.write("\t%s:\t%s\n\n" % (key, logging_options[key]))
        f.write("}\n")
 
@@ -261,16 +271,16 @@
                        for inf in totem_options["interface"]:
                                f.write("\tinterface {\n")
                                for k in inf.keys():
-                                       if inf[k] == "":
+                                       if inf[k] == "" or k == "oldlist":
                                                continue;
                                        else:
-                                               f.write("\t\t#%s\n\n" % 
(interface_option_table[k]["doc"]))
+                                               f.write("\t\t#%s\n" % 
(interface_option_table[k]["doc"]))
                                                f.write("\t\t%s:\t%s\n\n" % (k, 
inf[k]))
                                f.write("\t}\n")
                        continue
                if totem_options[key] == "":
                        continue
-               f.write("\t#%s\n\n" % (totem_option_table[key]["doc"]))
+               f.write("\t#%s\n" % (totem_option_table[key]["doc"]))
                f.write("\t%s:\t%s\n\n" % (key, totem_options[key]))
        # We print out all possible configurations as well
        # dont for now. looking for better solution
@@ -278,7 +288,7 @@
        for opt in totem_option_table.keys():
                v = totem_options.get(opt, None)
                if v == None:
-                       f.write("\t#%s\n\n" % (totem_option_table[opt]["doc"]))
+                       f.write("\t#%s\n" % (totem_option_table[opt]["doc"]))
                        f.write("\t#%s:\t%s\n\n" % (opt, 
totem_option_table[opt]["default_value"]))
        """
        f.write("}\n")
@@ -330,6 +340,10 @@
                                members = result.get("node", [])
                                members.append(opt_parser(file, 
node_option_table))
                                result["node"] = members
+                       elif i.lstrip().split(" ")[0] == "member":
+                               oldmembers = result.get("oldlist", [])
+                               oldmembers.append(opt_parser(file, 
old_memberlist_table))
+                               result["oldlist"] = oldmembers
                        else:
                                #y2warning("Unknown sub-directive %s found. 
Ignore it" % (i.lstrip().split(" ")[0]))
                                while (i[-1] != "}"):
@@ -394,16 +408,19 @@
        else:
                return None
 
-def generateMemberString(ringnum):
+# BNC#871970,combine ring0 and ring1 of one node into one struct
+# Only ring0 is available
+def generateMemberString():
        member_str = ""
 
-       ring_address = "ring%d_addr" % ringnum
-       #filter all nodes in a same ring
        for item in  nodelist_options.get("node"):
-               if item.has_key(ring_address):
-                       address = item.get(ring_address, None)
+               if item.has_key("ring0_addr"):
+                       address1 = item.get("ring0_addr", None)
+                       member_str += address1
+                       address2 = item.get("ring1_addr", None)
+                       if address2:
+                               member_str = member_str + ";" + address2
                        nodeid = item.get("nodeid", None)
-                       member_str += address
                        if nodeid:
                                member_str = member_str + ":" + nodeid
                        member_str = member_str + " "
@@ -415,6 +432,13 @@
                        del totem_options["interface"][i]
                        break
                
+# obsolete setting. BNC-879596, pop up a message if config file is in old 
format.
+def check_conf_format():
+       for x in range(len(totem_options["interface"])):
+               if totem_options["interface"][x].has_key("oldlist"):
+                       return "old"
+       return "new"
+
 def load_ais_conf(filename):
        try:
                f = open(filename, "r")
@@ -469,6 +493,9 @@
                                                        return '[]'
                                else:
                                        return '[]'
+               elif path_arr[0] == 'nodelist':
+                       if len(path_arr) == 1:
+                               return '["node"]'
                else:
                        return 'nil\n'
        
@@ -477,9 +504,11 @@
                        return "nil\n"
                elif path[0] == "quorum" and len(path) >= 2:
                        if path[1] == "expected_votes":
-                               return '"%s"' % 
quorum_options.get("expected_votes", "nil")
+                               return '"%s"' % 
quorum_options.get("expected_votes", "")
+                       if path[1] == "two_node":
+                               return '"%s"' % quorum_options.get("two_node", 
"")
                        else:
-                               return "nil"
+                               return ""
                elif path[0] == "totem":
                        if len(path) == 1:
                                return "nil"
@@ -517,8 +546,6 @@
                                                                return '"%d"' % 
i.get("mcastport", 5405)
                                                        if path[3] == "ttl":
                                                                return '"%d"' % 
i.get("ttl", 1)
-                                                       elif path[3] == 
"member":
-                                                               return 
generateMemberString(0)
                                                        else:
                                                                return "nil"
                                        elif path[2] == "interface1":
@@ -532,18 +559,28 @@
                                                                return '"%s"' % 
i.get("mcastaddr", "")
                                                        elif path[3] == 
"mcastport":
                                                                return '"%d"' % 
i.get("mcastport", 5405)
-                                                       elif path[3] == 
"member":
-                                                               return 
generateMemberString(1)
                                                        else:
                                                                return "nil"
+                                       elif path[2] == "member":
+                                               return '"%s"' % 
check_conf_format()
                                        else:
                                                return "nil"
                                else:
                                        return "nil"
                        else:
                                return "nil"
+               elif path[0] == "nodelist":
+                       if len(path[0]) == 1:
+                               return "nil"
+                       elif len(path) == 2:
+                               if path[1] == 'node':
+                                       return generateMemberString()
+                               else:
+                                       return "nil"
+                       else:
+                               return "nil"
                else:
-                       return "nil"
+                       return "nil"     # end of path[0]
 
 
        def saveFile(self):
@@ -573,10 +610,16 @@
        def doWrite(self, path, args):
                if path[0] == "":
                        self.saveFile()
+                       return "true"
                elif path[0] == "quorum":
                        if path[1] == "expected_votes":
                                quorum_options["expected_votes"] = args
                                return "true"
+                       elif path[1] == "two_node":
+                               quorum_options["two_node"] = args
+                               return "true"
+                       else:
+                               return "false"
                elif path[0] == "totem":
                        if len(path) == 2:
                                if path[1] == "autoid":
@@ -655,21 +698,6 @@
                                                                return "true"
                                                        except ValueError:
                                                                return "false"
-                                               elif path[3] == "member":
-                                                       member_addr_set = []
-                                                       ring_address = 
"ring%d_addr" % ring_num
-                                                       for member_address in 
args.strip().split(" "):
-                                                               colon_pos = 
member_address.find(":")
-                                                               if (colon_pos > 
-1):
-                                                                       
member_addr_set.append({ring_address:member_address[:colon_pos],"nodeid":member_address[colon_pos+1:]})
-                                                               else:
-                                                                       
member_addr_set.append({ring_address:member_address})
-                                                       #if ring_num=1,this is 
interface1. This means I already has interface0, so keep the previous nodelist 
options
-                                                       if (ring_num):
-                                                               
nodelist_options["node"] += member_addr_set
-                                                       else:
-                                                               
nodelist_options["node"] = member_addr_set
-                                                       return "true"
                                                else:
                                                        return "false"
                                        else:
@@ -678,6 +706,37 @@
                                        return "false"
                        else:
                                return "false"
+               elif path[0] == "nodelist":
+                       if len(path[0]) == 1:
+                               return "nil"
+                       elif len(path) == 2:
+                               if path[1] == 'node':
+                                       member_addr_set = []
+                                       # emtry string 's split will cause a 
[''] not []
+                                       if args == "":
+                                               nodelist_options["node"] = 
member_addr_set
+                                               return "nil"
+                                       for member_address in 
args.strip().split(" "):
+                                               colon_pos = 
member_address.find(":")
+                                               if (colon_pos > -1):
+                                                       tmpid = 
member_address[colon_pos+1:]
+                                                       semicolon_pos = 
member_address[:colon_pos].find(";")
+                                                       if (semicolon_pos > -1):
+                                                               
member_addr_set.append({"ring0_addr":member_address[:semicolon_pos],"ring1_addr":member_address[semicolon_pos+1:colon_pos],"nodeid":member_address[colon_pos+1:]})
+                                                       else:
+                                                               
member_addr_set.append({"ring0_addr":member_address[:colon_pos],"nodeid":member_address[colon_pos+1:]})
+                                               else:
+                                                       semicolon_pos = 
member_address[:colon_pos].find(";")
+                                                       if (semicolon_pos > -1):
+                                                               
member_addr_set.append({"ring0_addr":member_address[:semicolon_pos],"ring1_addr":member_address[semicolon_pos+1:]})
+                                                       else:
+                                                               
member_addr_set.append({"ring0_addr":member_address})
+                                       nodelist_options["node"] = 
member_addr_set
+                                       return "true"
+                               else:
+                                       return "nil"
+                       else:
+                               return "nil"
                else:
                        return "false"
                return "false"
@@ -698,6 +757,7 @@
                
                #y2debug ("newline: %s" % scr_command);
                
+               # eg. Read(.totem.interface.interface0.binnetaddr,"args")  
Write(.)
                p = re.compile('^`?(\w+)\s*(\(([^,]*)(,\s*(.*))?\s*\))?\s*$')
                r = p.match(scr_command)
                if (r):

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to