Hello community,

here is the log from the commit of package crmsh for openSUSE:Factory checked 
in at 2020-07-24 10:07:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/crmsh (Old)
 and      /work/SRC/openSUSE:Factory/.crmsh.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "crmsh"

Fri Jul 24 10:07:32 2020 rev:188 rq:822449 version:4.2.0+git.1595517298.a06e892f

Changes:
--------
--- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes      2020-07-17 
20:50:10.372877903 +0200
+++ /work/SRC/openSUSE:Factory/.crmsh.new.3592/crmsh.changes    2020-07-24 
10:09:12.138124654 +0200
@@ -1,0 +2,7 @@
+Thu Jul 23 15:28:41 UTC 2020 - xli...@suse.com
+
+- Update to version 4.2.0+git.1595517298.a06e892f:
+  * Dev: unittest: append unit test for corosync status related codes
+  * Low: ui_corosync: copy ssh key to qnetd while detect need 
password(bsc#1174385)
+
+-------------------------------------------------------------------

Old:
----
  crmsh-4.2.0+git.1594286044.7a596d12.tar.bz2

New:
----
  crmsh-4.2.0+git.1595517298.a06e892f.tar.bz2

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

Other differences:
------------------
++++++ crmsh.spec ++++++
--- /var/tmp/diff_new_pack.wvBXfz/_old  2020-07-24 10:09:16.502129030 +0200
+++ /var/tmp/diff_new_pack.wvBXfz/_new  2020-07-24 10:09:16.506129034 +0200
@@ -36,7 +36,7 @@
 Summary:        High Availability cluster command-line interface
 License:        GPL-2.0-or-later
 Group:          %{pkg_group}
-Version:        4.2.0+git.1594286044.7a596d12
+Version:        4.2.0+git.1595517298.a06e892f
 Release:        0
 Url:            http://crmsh.github.io
 Source0:        %{name}-%{version}.tar.bz2

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.wvBXfz/_old  2020-07-24 10:09:16.546129074 +0200
+++ /var/tmp/diff_new_pack.wvBXfz/_new  2020-07-24 10:09:16.546129074 +0200
@@ -5,4 +5,4 @@
                 <param 
name="url">https://github.com/liangxin1300/crmsh.git</param>
               <param 
name="changesrevision">d8dc51b4cb34964aa72e918999ebc7f03b48f3c9</param></service><service
 name="tar_scm">
                 <param 
name="url">https://github.com/ClusterLabs/crmsh.git</param>
-              <param 
name="changesrevision">78ce77e47b195fc2ef4a21d5d83886b178bbc0e1</param></service></servicedata>
\ No newline at end of file
+              <param 
name="changesrevision">314ca14d291ce6c6856ff4571b6e59b3d4df9f10</param></service></servicedata>
\ No newline at end of file

++++++ crmsh-4.2.0+git.1594286044.7a596d12.tar.bz2 -> 
crmsh-4.2.0+git.1595517298.a06e892f.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.2.0+git.1594286044.7a596d12/crmsh/corosync.py 
new/crmsh-4.2.0+git.1595517298.a06e892f/crmsh/corosync.py
--- old/crmsh-4.2.0+git.1594286044.7a596d12/crmsh/corosync.py   2020-07-09 
11:14:04.000000000 +0200
+++ new/crmsh-4.2.0+git.1595517298.a06e892f/crmsh/corosync.py   2020-07-23 
17:14:58.000000000 +0200
@@ -36,6 +36,73 @@
     return utils.get_stdout(['corosync-quorumtool'] + list(args), shell=False)
 
 
+def query_status(status_type):
+    """
+    Query status of corosync
+
+    Possible types could be ring/quorum/qnetd
+    """
+    if status_type == "ring":
+        query_ring_status()
+    elif status_type == "quorum":
+        query_quorum_status()
+    elif status_type == "qnetd":
+        query_qnetd_status()
+    else:
+        raise ValueError("Wrong type \"{}\" to query 
status".format(status_type))
+
+
+def query_ring_status():
+    """
+    Query corosync ring status
+    """
+    rc, out, err = utils.get_stdout_stderr("corosync-cfgtool -s")
+    if rc != 0 and err:
+        raise ValueError(err)
+    if rc == 0 and out:
+        print(out)
+
+
+def query_quorum_status():
+    """
+    Query corosync quorum status
+    """
+    utils.print_cluster_nodes()
+    rc, out, err = utils.get_stdout_stderr("corosync-quorumtool -s")
+    if rc != 0 and err:
+        raise ValueError(err)
+    if rc == 0 and out:
+        print(out)
+
+
+def query_qnetd_status():
+    """
+    Query qnetd status
+    """
+    if not utils.is_qdevice_configured():
+        raise ValueError("QDevice/QNetd not configured!")
+    cluster_name = get_value('totem.cluster_name')
+    if not cluster_name:
+        raise ValueError("cluster_name not configured!")
+    qnetd_addr = get_value('quorum.device.net.host')
+    if not qnetd_addr:
+        raise ValueError("host for qnetd not configured!")
+
+    # Configure ssh passwordless to qnetd if detect password is needed
+    if utils.check_ssh_passwd_need(qnetd_addr):
+        print("Copy ssh key to qnetd node({})".format(qnetd_addr))
+        rc, _, err = utils.get_stdout_stderr("ssh-copy-id -i 
/root/.ssh/id_rsa.pub root@{}".format(qnetd_addr))
+        if rc != 0:
+            raise ValueError(err)
+
+    cmd = "corosync-qnetd-tool -lv -c {}".format(cluster_name)
+    result = parallax.parallax_call([qnetd_addr], cmd)
+    _, qnetd_result_stdout, _ = result[0][1]
+    if qnetd_result_stdout:
+        utils.print_cluster_nodes()
+        print(utils.to_ascii(qnetd_result_stdout))
+
+
 _tCOMMENT = 0
 _tBEGIN = 1
 _tEND = 2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.2.0+git.1594286044.7a596d12/crmsh/ui_corosync.py 
new/crmsh-4.2.0+git.1595517298.a06e892f/crmsh/ui_corosync.py
--- old/crmsh-4.2.0+git.1594286044.7a596d12/crmsh/ui_corosync.py        
2020-07-09 11:14:04.000000000 +0200
+++ new/crmsh-4.2.0+git.1595517298.a06e892f/crmsh/ui_corosync.py        
2020-07-23 17:14:58.000000000 +0200
@@ -8,6 +8,7 @@
 from .msg import err_buf
 from . import corosync
 from . import parallax
+from . import bootstrap
 
 
 def _push_completer(args):
@@ -62,47 +63,15 @@
         '''
         Quick cluster health status. Corosync status or QNetd status
         '''
-        def print_cluster_nodes():
-            rc, out = utils.get_stdout("crm_node -l")
-            if rc == 0 and out:
-                print("{}\n".format(out))
-
-        rc, _ = utils.get_stdout('systemctl -q is-active corosync.service')
-        if rc != 0:
+        if not bootstrap.service_is_active("corosync.service"):
             err_buf.error("corosync.service is not running!")
             return False
 
-        if status_type == "ring":
-            print(corosync.cfgtool('-s')[1])
-            return
-        if status_type == "quorum":
-            print_cluster_nodes()
-            print(corosync.quorumtool('-s')[1])
-            return
-        if status_type == "qnetd":
-            if not utils.is_qdevice_configured():
-                err_buf.error("QDevice/QNetd not configured!")
-                return False
-            cluster_name = corosync.get_value('totem.cluster_name')
-            if not cluster_name:
-                err_buf.error("cluster_name not configured!")
-                return False
-            qnetd_addr = corosync.get_value('quorum.device.net.host')
-            if not qnetd_addr:
-                err_buf.error("host for qnetd not configured!")
-                return False
-
-            cmd = "corosync-qnetd-tool -lv -c {}".format(cluster_name)
-            try:
-                result = parallax.parallax_call([qnetd_addr], cmd)
-            except ValueError as err:
-                err_buf.error(err)
-                return False
-            _, qnetd_result_stdout, _ = result[0][1]
-            if qnetd_result_stdout:
-                print_cluster_nodes()
-                print(utils.to_ascii(qnetd_result_stdout))
-            return
+        try:
+            corosync.query_status(status_type)
+        except ValueError as err:
+            err_buf.error(str(err))
+            return False
 
     @command.skill_level('administrator')
     def do_reload(self, context):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.2.0+git.1594286044.7a596d12/crmsh/utils.py 
new/crmsh-4.2.0+git.1595517298.a06e892f/crmsh/utils.py
--- old/crmsh-4.2.0+git.1594286044.7a596d12/crmsh/utils.py      2020-07-09 
11:14:04.000000000 +0200
+++ new/crmsh-4.2.0+git.1595517298.a06e892f/crmsh/utils.py      2020-07-23 
17:14:58.000000000 +0200
@@ -1664,6 +1664,15 @@
         return []
 
 
+def print_cluster_nodes():
+    """
+    Print the output of crm_node -l
+    """
+    rc, out, _ = get_stdout_stderr("crm_node -l")
+    if rc == 0 and out:
+        print("{}\n".format(out))
+
+
 def list_cluster_nodes():
     '''
     Returns a list of nodes in the cluster.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.2.0+git.1594286044.7a596d12/test/unittests/test_corosync.py 
new/crmsh-4.2.0+git.1595517298.a06e892f/test/unittests/test_corosync.py
--- old/crmsh-4.2.0+git.1594286044.7a596d12/test/unittests/test_corosync.py     
2020-07-09 11:14:04.000000000 +0200
+++ new/crmsh-4.2.0+git.1595517298.a06e892f/test/unittests/test_corosync.py     
2020-07-23 17:14:58.000000000 +0200
@@ -9,6 +9,7 @@
 from builtins import object
 import os
 import unittest
+import pytest
 from unittest import mock
 from crmsh import corosync
 from crmsh.corosync import Parser, make_section, make_value
@@ -40,6 +41,149 @@
     print(parser.to_string())
 
 
+@mock.patch("crmsh.corosync.query_ring_status")
+def test_query_status_ring(mock_ring_status):
+    corosync.query_status("ring")
+    mock_ring_status.assert_called_once_with()
+
+
+@mock.patch("crmsh.corosync.query_quorum_status")
+def test_query_status_quorum(mock_quorum_status):
+    corosync.query_status("quorum")
+    mock_quorum_status.assert_called_once_with()
+
+
+@mock.patch("crmsh.corosync.query_qnetd_status")
+def test_query_status_qnetd(mock_qnetd_status):
+    corosync.query_status("qnetd")
+    mock_qnetd_status.assert_called_once_with()
+
+
+def test_query_status_except():
+    with pytest.raises(ValueError) as err:
+        corosync.query_status("xxx")
+    assert str(err.value) == "Wrong type \"xxx\" to query status"
+
+
+@mock.patch("crmsh.utils.get_stdout_stderr")
+def test_query_ring_status_except(mock_run):
+    mock_run.return_value = (1, None, "error")
+    with pytest.raises(ValueError) as err:
+        corosync.query_ring_status()
+    assert str(err.value) == "error"
+    mock_run.assert_called_once_with("corosync-cfgtool -s")
+
+
+@mock.patch("crmsh.utils.get_stdout_stderr")
+def test_query_ring_status(mock_run):
+    mock_run.return_value = (0, "data", None)
+    corosync.query_ring_status()
+    mock_run.assert_called_once_with("corosync-cfgtool -s")
+
+
+@mock.patch("crmsh.utils.print_cluster_nodes")
+@mock.patch("crmsh.utils.get_stdout_stderr")
+def test_query_quorum_status_except(mock_run, mock_print_nodes):
+    mock_run.return_value = (1, None, "error")
+    with pytest.raises(ValueError) as err:
+        corosync.query_quorum_status()
+    assert str(err.value) == "error"
+    mock_run.assert_called_once_with("corosync-quorumtool -s")
+    mock_print_nodes.assert_called_once_with()
+
+
+@mock.patch("crmsh.utils.print_cluster_nodes")
+@mock.patch("crmsh.utils.get_stdout_stderr")
+def test_query_quorum_status(mock_run, mock_print_nodes):
+    mock_run.return_value = (0, "data", None)
+    corosync.query_quorum_status()
+    mock_run.assert_called_once_with("corosync-quorumtool -s")
+    mock_print_nodes.assert_called_once_with()
+
+
+@mock.patch("crmsh.utils.is_qdevice_configured")
+def test_query_qnetd_status_no_qdevice(mock_qdevice_configured):
+    mock_qdevice_configured.return_value = False
+    with pytest.raises(ValueError) as err:
+        corosync.query_qnetd_status()
+    assert str(err.value) == "QDevice/QNetd not configured!"
+    mock_qdevice_configured.assert_called_once_with()
+
+
+@mock.patch("crmsh.corosync.get_value")
+@mock.patch("crmsh.utils.is_qdevice_configured")
+def test_query_qnetd_status_no_cluster_name(mock_qdevice_configured, 
mock_get_value):
+    mock_qdevice_configured.return_value = True
+    mock_get_value.return_value = None
+    with pytest.raises(ValueError) as err:
+        corosync.query_qnetd_status()
+    assert str(err.value) == "cluster_name not configured!"
+    mock_qdevice_configured.assert_called_once_with()
+    mock_get_value.assert_called_once_with("totem.cluster_name")
+
+
+@mock.patch("crmsh.corosync.get_value")
+@mock.patch("crmsh.utils.is_qdevice_configured")
+def test_query_qnetd_status_no_cluster_name(mock_qdevice_configured, 
mock_get_value):
+    mock_qdevice_configured.return_value = True
+    mock_get_value.side_effect = ["hacluster", None]
+    with pytest.raises(ValueError) as err:
+        corosync.query_qnetd_status()
+    assert str(err.value) == "host for qnetd not configured!"
+    mock_qdevice_configured.assert_called_once_with()
+    mock_get_value.assert_has_calls([
+        mock.call("totem.cluster_name"),
+        mock.call("quorum.device.net.host")
+        ])
+
+
+@mock.patch("crmsh.utils.get_stdout_stderr")
+@mock.patch("crmsh.utils.check_ssh_passwd_need")
+@mock.patch("crmsh.corosync.get_value")
+@mock.patch("crmsh.utils.is_qdevice_configured")
+def test_query_qnetd_status_copy_id_failed(mock_qdevice_configured, 
mock_get_value, mock_check_passwd, mock_run):
+    mock_qdevice_configured.return_value = True
+    mock_get_value.side_effect = ["hacluster", "10.10.10.123"]
+    mock_check_passwd.return_value = True
+    mock_run.return_value = [1, None, "error"]
+    with pytest.raises(ValueError) as err:
+        corosync.query_qnetd_status()
+    assert str(err.value) == "error"
+    mock_qdevice_configured.assert_called_once_with()
+    mock_get_value.assert_has_calls([
+        mock.call("totem.cluster_name"),
+        mock.call("quorum.device.net.host")
+        ])
+    mock_check_passwd.assert_called_once_with("10.10.10.123")
+    mock_run.assert_called_once_with("ssh-copy-id -i /root/.ssh/id_rsa.pub 
root@10.10.10.123")
+
+
+@mock.patch("crmsh.utils.print_cluster_nodes")
+@mock.patch("crmsh.parallax.parallax_call")
+@mock.patch("crmsh.utils.get_stdout_stderr")
+@mock.patch("crmsh.utils.check_ssh_passwd_need")
+@mock.patch("crmsh.corosync.get_value")
+@mock.patch("crmsh.utils.is_qdevice_configured")
+def test_query_qnetd_status_copy(mock_qdevice_configured, mock_get_value, 
mock_check_passwd, mock_run, mock_parallax_call, mock_print_nodes):
+    mock_qdevice_configured.return_value = True
+    mock_get_value.side_effect = ["hacluster", "10.10.10.123"]
+    mock_check_passwd.return_value = True
+    mock_run.return_value = [0, "data", None]
+    mock_parallax_call.return_value = [("node1", (0, "data", None)), ]
+
+    corosync.query_qnetd_status()
+
+    mock_qdevice_configured.assert_called_once_with()
+    mock_get_value.assert_has_calls([
+        mock.call("totem.cluster_name"),
+        mock.call("quorum.device.net.host")
+        ])
+    mock_check_passwd.assert_called_once_with("10.10.10.123")
+    mock_run.assert_called_once_with("ssh-copy-id -i /root/.ssh/id_rsa.pub 
root@10.10.10.123")
+    mock_parallax_call.assert_called_once_with(["10.10.10.123"], 
"corosync-qnetd-tool -lv -c hacluster")
+    mock_print_nodes.assert_called_once_with()
+
+
 class TestCorosyncParser(unittest.TestCase):
     def test_parse(self):
         p = Parser(F1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.2.0+git.1594286044.7a596d12/test/unittests/test_utils.py 
new/crmsh-4.2.0+git.1595517298.a06e892f/test/unittests/test_utils.py
--- old/crmsh-4.2.0+git.1594286044.7a596d12/test/unittests/test_utils.py        
2020-07-09 11:14:04.000000000 +0200
+++ new/crmsh-4.2.0+git.1595517298.a06e892f/test/unittests/test_utils.py        
2020-07-23 17:14:58.000000000 +0200
@@ -22,6 +22,13 @@
     imp.reload(utils)
 
 
+@mock.patch("crmsh.utils.get_stdout_stderr")
+def test_print_cluster_nodes(mock_run):
+    mock_run.return_value = (0, "data", None)
+    utils.print_cluster_nodes()
+    mock_run.assert_called_once_with("crm_node -l")
+
+
 @mock.patch('os.path.exists')
 def test_check_file_content_included_target_not_exist(mock_exists):
     mock_exists.side_effect = [True, False]


Reply via email to