summaryrefslogtreecommitdiffstats
path: root/debian/patches
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/0003-Add-remote-resource-to-local-cache.patchbin0 -> 10133 bytes
-rw-r--r--debian/patches/0004-Fix-privacy-breach-generic-caused-by-footer-template.patch25
-rw-r--r--debian/patches/0005-Fix-privacy-breach-generic-caused-by-atom-xml-templa.patch28
-rw-r--r--debian/patches/0006-Fix-privacy-breach-generic-caused-by-youtube-iframe.patch26
-rw-r--r--debian/patches/0007-pygmentize-lexer.patch81
-rw-r--r--debian/patches/0010-Fix-package-management.patch33
-rw-r--r--debian/patches/0011-Fix-scripts-init.patch14
-rw-r--r--debian/patches/0012-Fix-crm-history.patch24
-rw-r--r--debian/patches/0013-Fix-cluster-bootstrap.patch70
-rw-r--r--debian/patches/0014-Fix-cluster-stop-start.patch17
-rw-r--r--debian/patches/0015-Fix-testsuite-errors.patch188
-rw-r--r--debian/patches/0016-Fix-python2-calls.patch138
-rw-r--r--debian/patches/0017-Fix-profiles-adoc.patch17
-rw-r--r--debian/patches/0018-Fix-python3-install.patch16
-rw-r--r--debian/patches/0019-Remove-news-adoc.patch34
-rw-r--r--debian/patches/0020-Replace-distutils.patch75
-rw-r--r--debian/patches/0021-Fix-bootstrap-bash.patch25
-rw-r--r--debian/patches/series17
18 files changed, 828 insertions, 0 deletions
diff --git a/debian/patches/0003-Add-remote-resource-to-local-cache.patch b/debian/patches/0003-Add-remote-resource-to-local-cache.patch
new file mode 100644
index 0000000..8f966d5
--- /dev/null
+++ b/debian/patches/0003-Add-remote-resource-to-local-cache.patch
Binary files differ
diff --git a/debian/patches/0004-Fix-privacy-breach-generic-caused-by-footer-template.patch b/debian/patches/0004-Fix-privacy-breach-generic-caused-by-footer-template.patch
new file mode 100644
index 0000000..5da4a07
--- /dev/null
+++ b/debian/patches/0004-Fix-privacy-breach-generic-caused-by-footer-template.patch
@@ -0,0 +1,25 @@
+From: Richard B Winters <rik@mmogp.com>
+Date: Fri, 29 Jan 2016 10:43:26 -0500
+Subject: Fix privacy-breach-generic caused by footer template
+
+ - An image fetched from githubuserconent needs to be
+ replaced with a local cache to avoid the
+ aforementioned lintian informational warning
+
+Change-Id: I3798ca0f774161ed6d99d0da25369ad421e69397
+Signed-off-by: Richard B Winters <rik@mmogp.com>
+---
+ doc/website-v1/crm.conf | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/doc/website-v1/crm.conf
++++ b/doc/website-v1/crm.conf
+@@ -589,7 +589,7 @@
+ </div>
+ </div>
+
+-<a href="https://github.com/ClusterLabs/crmsh"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"></a>
++<a href="https://github.com/ClusterLabs/crmsh"><img style="position: absolute; top: 0; right: 0; border: 0;" src="/img/fork-me-on-github.png" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>
+
+ </body>
+ </html>
diff --git a/debian/patches/0005-Fix-privacy-breach-generic-caused-by-atom-xml-templa.patch b/debian/patches/0005-Fix-privacy-breach-generic-caused-by-atom-xml-templa.patch
new file mode 100644
index 0000000..beb880b
--- /dev/null
+++ b/debian/patches/0005-Fix-privacy-breach-generic-caused-by-atom-xml-templa.patch
@@ -0,0 +1,28 @@
+From: Richard B Winters <rik@mmogp.com>
+Date: Fri, 29 Jan 2016 10:43:46 -0500
+Subject: Fix privacy-breach-generic caused by atom xml template
+
+ - Modifies the atom xml template so as not to breach
+ privacy by using remote resources.
+
+Change-Id: I0043f9815620a3b88546c481f416b6ebebe66472
+Signed-off-by: Richard B Winters <rik@mmogp.com>
+---
+ doc/website-v1/make-news.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/doc/website-v1/make-news.py b/doc/website-v1/make-news.py
+index f3c9073..89271d2 100644
+--- a/doc/website-v1/make-news.py
++++ b/doc/website-v1/make-news.py
+@@ -21,8 +21,8 @@ ATOM_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?>
+ <feed xmlns="http://www.w3.org/2005/Atom">
+ <title>crmsh</title>
+ <subtitle>Cluster manager shell news</subtitle>
+-<link href="http://crmsh.github.io/atom.xml" rel="self" />
+-<link href="http://crmsh.github.io/" />
++<link href="/atom.xml" rel="self" />
++<link href="/" />
+ <id>%(id)s</id>
+ <updated>%(updated)s</updated>
+ %(entries)s
diff --git a/debian/patches/0006-Fix-privacy-breach-generic-caused-by-youtube-iframe.patch b/debian/patches/0006-Fix-privacy-breach-generic-caused-by-youtube-iframe.patch
new file mode 100644
index 0000000..074aef2
--- /dev/null
+++ b/debian/patches/0006-Fix-privacy-breach-generic-caused-by-youtube-iframe.patch
@@ -0,0 +1,26 @@
+From: Richard B Winters <rik@mmogp.com>
+Date: Fri, 29 Jan 2016 11:26:22 -0500
+Subject: Fix privacy-breach-generic caused by youtube iframe
+
+ - Modified 2015-05-13-releaswe-2_1_4.adoc so as not to
+ embed the youtube video
+
+Change-Id: Iaaf487ace95f5c5b02ba5f89d796e08e9abab4fd
+Signed-off-by: Richard B Winters <rik@mmogp.com>
+---
+ doc/website-v1/news/2015-05-13-release-2_1_4.adoc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/doc/website-v1/news/2015-05-13-release-2_1_4.adoc b/doc/website-v1/news/2015-05-13-release-2_1_4.adoc
+index 31297cf..e1dc9df 100644
+--- a/doc/website-v1/news/2015-05-13-release-2_1_4.adoc
++++ b/doc/website-v1/news/2015-05-13-release-2_1_4.adoc
+@@ -50,7 +50,7 @@ builds upon the crmsh history feature at openSUSE conf in The Hague
+ earlier this month. The video of that presentation is online here:
+
+ ++++++++++++
+-<iframe width="420" height="315" src="https://www.youtube.com/embed/mngfxzXkFLw" frameborder="0" allowfullscreen></iframe>
++<iframe width="420" height="315" src="/" frameborder="0" allowfullscreen></iframe>
+ ++++++++++++
+
+ https://www.youtube.com/watch?v=mngfxzXkFLw
diff --git a/debian/patches/0007-pygmentize-lexer.patch b/debian/patches/0007-pygmentize-lexer.patch
new file mode 100644
index 0000000..153edd3
--- /dev/null
+++ b/debian/patches/0007-pygmentize-lexer.patch
@@ -0,0 +1,81 @@
+From: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+Subject: Patch to avoid using the custom lexer
+ This patch makes some changes to the crmsh doc build so it doesn't use
+ the included custom lexer.
+Forwarded: not-needed
+Last-Update: 2016-09-23
+
+--- a/doc/website-v1/history-guide.adoc
++++ b/doc/website-v1/history-guide.adoc
+@@ -51,7 +51,7 @@
+ preparing this document we noticed that a probe failed repeatedly
+ on a node which wasn't even running the resource <<Listing 2>>.
+
+-[source,ansiclr]
++[source,c]
+ [caption="Listing 2: "]
+ .crm status output[[Listing 2]]
+ -----------------
+@@ -61,7 +61,7 @@
+ The history +resource+ command shows log messages relevant to the
+ supplied resource <<Listing 3>>.
+
+-[source,ansiclr]
++[source,c]
+ [caption="Listing 3: "]
+ .Logs on failed +nfs-server+ probe operation[[Listing 3]]
+ -----------------
+@@ -88,7 +88,7 @@
+ tracing of the resource agent. <<Listing 4>> shows how to do
+ that.
+
+-[source,ansiclr]
++[source,c]
+ [caption="Listing 4: "]
+ .Set `nfs-server` probe operation resource tracing[[Listing 4]]
+ -----------------
+@@ -126,7 +126,7 @@
+ To begin, we run the `info` command which gives an overview, as
+ shown in <<Listing 5>>.
+
+-[source,ansiclr]
++[source,c]
+ [caption="Listing 5: "]
+ .Basic history information[[Listing 5]]
+ -----------------
+@@ -155,7 +155,7 @@
+ The listing is annotated to explain the output in more detail.
+
+
+-[source,ansiclr]
++[source,c]
+ [caption="Listing 6: "]
+ .Viewing transitions[[Listing 6]]
+ -----------------
+@@ -194,7 +194,7 @@
+ It may sometimes be useful to see what changed between two
+ transitions. History `diff` command is in action in <<Listing 7>>.
+
+-[source,ansiclr]
++[source,c]
+ [caption="Listing 7: "]
+ .Viewing transitions[[Listing 7]]
+ -----------------
+@@ -212,7 +212,7 @@
+ actions of that transition are yet to be executed. So, the status
+ section of transition _N_ corresponds to the configuration _N-1_.
+
+-[source,ansiclr]
++[source,c]
+ [caption="Listing 8: "]
+ .Full transition log[[Listing 8]]
+ -----------------
+@@ -232,7 +232,7 @@
+ recommendable), then use the history `detail` command to
+ increase the level of detail displayed.
+
+-[source,ansiclr]
++[source,c]
+ [caption="Listing 9: "]
+ .Resource related messages[[Listing 9]]
+ -----------------
diff --git a/debian/patches/0010-Fix-package-management.patch b/debian/patches/0010-Fix-package-management.patch
new file mode 100644
index 0000000..a4da58f
--- /dev/null
+++ b/debian/patches/0010-Fix-package-management.patch
@@ -0,0 +1,33 @@
+Description: Use dpkg and apt for package management
+Author: Valentin Vidic <Valentin.Vidic@CARNet.hr>
+Last-Update: 2019-01-12
+--- a/utils/crm_init.py
++++ b/utils/crm_init.py
+@@ -27,12 +27,12 @@
+ def service_info(service):
+ "Returns information about a given service"
+ active, enabled = 'unknown', 'unknown'
+- rc, out, err = crm_script.call(["/usr/bin/systemctl", "is-enabled", "%s.service" % (service)])
++ rc, out, err = crm_script.call(["/bin/systemctl", "is-enabled", "%s.service" % (service)])
+ if rc in (0, 1, 3) and out:
+ enabled = out.strip()
+ else:
+ return {'name': service, 'error': err.strip()}
+- rc, out, err = crm_script.call(["/usr/bin/systemctl", "is-active", "%s.service" % (service)])
++ rc, out, err = crm_script.call(["/bin/systemctl", "is-active", "%s.service" % (service)])
+ if rc in (0, 1, 3) and out:
+ active = out.strip()
+ else:
+--- a/utils/crm_script.py
++++ b/utils/crm_script.py
+@@ -133,8 +133,8 @@
+
+ def service(name, action):
+ if action.startswith('is-'):
+- return call(['/usr/bin/systemctl', action, name + '.service'])
+- return sudo_call(['/usr/bin/systemctl', action, name + '.service'])
++ return call(['/bin/systemctl', action, name + '.service'])
++ return sudo_call(['/bin/systemctl', action, name + '.service'])
+
+
+ def package(name, state):
diff --git a/debian/patches/0011-Fix-scripts-init.patch b/debian/patches/0011-Fix-scripts-init.patch
new file mode 100644
index 0000000..dfdef5a
--- /dev/null
+++ b/debian/patches/0011-Fix-scripts-init.patch
@@ -0,0 +1,14 @@
+Description: Make cluster init work on Debian
+Author: Valentin Vidic <Valentin.Vidic@CARNet.hr>
+Last-Update: 2016-11-19
+--- a/crmsh/corosync.py
++++ b/crmsh/corosync.py
+@@ -609,7 +609,7 @@
+ fileline: off
+ to_stderr: no
+ to_logfile: yes
+- logfile: /var/log/cluster/corosync.log
++ logfile: /var/log/corosync/corosync.log
+ to_syslog: yes
+ debug: off
+ timestamp: on
diff --git a/debian/patches/0012-Fix-crm-history.patch b/debian/patches/0012-Fix-crm-history.patch
new file mode 100644
index 0000000..614fc01
--- /dev/null
+++ b/debian/patches/0012-Fix-crm-history.patch
@@ -0,0 +1,24 @@
+Description: Fix detection of cluster events
+ hb_report looks at /var/log/messages for cluster events by default.
+ On Debian systems this file only contains kernel messages so we use
+ /var/log/syslog instead.
+ .
+ Since the pacemaker looging moved to /var/log/pacemaker.log rather
+ than syslog, only this new file contains info on transitions so
+ use it instead of standard syslog messaging.
+Author: Valentin Vidic <Valentin.Vidic@CARNet.hr>
+Bug: https://github.com/ClusterLabs/crmsh/issues/169
+Last-Update: 2019-01-12
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/crmsh/history.py
++++ b/crmsh/history.py
+@@ -21,7 +21,7 @@
+ logger = log.setup_logger(__name__)
+
+
+-_LOG_FILES = ("ha-log.txt", "messages", "ha-log", "cluster-log.txt", "journal.log", "pacemaker.log")
++_LOG_FILES = ("ha-log.txt", "syslog", "ha-log", "cluster-log.txt", "journal.log", "pacemaker.log")
+
+
+ #
diff --git a/debian/patches/0013-Fix-cluster-bootstrap.patch b/debian/patches/0013-Fix-cluster-bootstrap.patch
new file mode 100644
index 0000000..342d3fd
--- /dev/null
+++ b/debian/patches/0013-Fix-cluster-bootstrap.patch
@@ -0,0 +1,70 @@
+Description: Fix cluster init on Debian
+ Update file paths and service names to work better on Debian.
+Author: Valentin Vidic <Valentin.Vidic@CARNet.hr>
+Last-Update: 2019-01-12
+--- a/crmsh/utils.py
++++ b/crmsh/utils.py
+@@ -2495,13 +2495,13 @@
+ """
+ Check if package is installed
+ """
+- cmd = "rpm -q --quiet {}".format(pkg)
++ cmd = "dpkg-query --status {}".format(pkg)
+ if remote_addr:
+ # check on remote
+ rc, _, _ = sh.cluster_shell().get_rc_stdout_stderr_without_input(remote_addr, cmd)
+ else:
+ # check on local
+- rc, _ = ShellUtils().get_stdout(cmd)
++ rc, _, _ = ShellUtils().get_stdout_stderr(cmd)
+ return rc == 0
+
+
+--- a/crmsh/bootstrap.py
++++ b/crmsh/bootstrap.py
+@@ -52,12 +52,12 @@
+ logger_utils = log.LoggerUtils(logger)
+
+
+-CSYNC2_KEY = "/etc/csync2/key_hagroup"
+-CSYNC2_CFG = "/etc/csync2/csync2.cfg"
++CSYNC2_KEY = "/etc/csync2.key_hagroup"
++CSYNC2_CFG = "/etc/csync2.cfg"
+ COROSYNC_AUTH = "/etc/corosync/authkey"
+ CRM_CFG = "/etc/crm/crm.conf"
+ PROFILES_FILE = "/etc/crm/profiles.yml"
+-SYSCONFIG_SBD = "/etc/sysconfig/sbd"
++SYSCONFIG_SBD = "/etc/default/sbd"
+ SYSCONFIG_PCMK = "/etc/sysconfig/pacemaker"
+ SYSCONFIG_NFS = "/etc/sysconfig/nfs"
+ SYSCONFIG_FW = "/etc/sysconfig/SuSEfirewall2"
+@@ -1385,7 +1385,7 @@
+ clustername=_context.cluster_name,
+ ringXaddr=ringXaddr_res,
+ mcastport=mcastport_res,
+- transport="udpu",
++ transport="knet",
+ ipv6=_context.ipv6,
+ two_rings=two_rings)
+ sync_file(corosync.conf())
+--- a/crmsh/corosync.py
++++ b/crmsh/corosync.py
+@@ -643,7 +643,7 @@
+ two_rings=False,
+ qdevice=None):
+
+- if transport == "udpu":
++ if transport == "knet":
+ ring_tmpl = ""
+ for i in 0, 1:
+ ring_tmpl += " ring{}_addr: {}\n".format(i, ringXaddr[i])
+@@ -682,6 +682,9 @@
+ expected_votes: 1
+ two_node: 0
+ }
++resources {
++ watchdog_device: off
++}
+ """
+ if qdevice is not None:
+ quorum_tmpl = """quorum {
diff --git a/debian/patches/0014-Fix-cluster-stop-start.patch b/debian/patches/0014-Fix-cluster-stop-start.patch
new file mode 100644
index 0000000..a36b5eb
--- /dev/null
+++ b/debian/patches/0014-Fix-cluster-stop-start.patch
@@ -0,0 +1,17 @@
+Description: Fix crm cluster stop/start on Debian
+ Corosync remains running after 'crm cluster stop'.
+ Don't rely on systemd service dependencies to stop it
+ and also make it work with sysv init.
+Author: Valentin Vidic <Valentin.Vidic@CARNet.hr>
+Last-Update: 2017-10-20
+--- a/crmsh/ui_cluster.py
++++ b/crmsh/ui_cluster.py
+@@ -170,7 +170,7 @@
+ '''
+ Starts the cluster stack on all nodes or specific node(s)
+ '''
+- service_check_list = ["pacemaker.service"]
++ service_check_list = ["corosync.service", "pacemaker.service"]
+ start_qdevice = False
+ if utils.is_qdevice_configured():
+ start_qdevice = True
diff --git a/debian/patches/0015-Fix-testsuite-errors.patch b/debian/patches/0015-Fix-testsuite-errors.patch
new file mode 100644
index 0000000..b93250a
--- /dev/null
+++ b/debian/patches/0015-Fix-testsuite-errors.patch
@@ -0,0 +1,188 @@
+Description: Fix testsuite
+ Make sure testsuite output works with Pacemaker 2.
+Author: Valentin Vidic <vvidic@debian.org>
+Last-Update: 2021-02-03
+--- a/test/unittests/test_utils.py
++++ b/test/unittests/test_utils.py
+@@ -34,12 +34,12 @@
+ mock_run.assert_called_once_with("crm_node -l")
+
+
+-@mock.patch("crmsh.sh.ShellUtils.get_stdout")
++@mock.patch("crmsh.sh.ShellUtils.get_stdout_stderr")
+ def test_package_is_installed_local(mock_run):
+- mock_run.return_value = (0, None)
++ mock_run.return_value = (0, None, None)
+ res = utils.package_is_installed("crmsh")
+ assert res is True
+- mock_run.assert_called_once_with("rpm -q --quiet crmsh")
++ mock_run.assert_called_once_with("dpkg-query --status crmsh")
+
+
+ @mock.patch('crmsh.utils.detect_file')
+--- a/test/unittests/test_sbd.py
++++ b/test/unittests/test_sbd.py
+@@ -512,9 +512,9 @@
+
+ self.sbd_inst._update_sbd_configuration()
+
+- mock_copy.assert_called_once_with("/usr/share/fillup-templates/sysconfig.sbd", "/etc/sysconfig/sbd")
+- mock_sysconfig.assert_called_once_with("/etc/sysconfig/sbd", SBD_WATCHDOG_DEV='/dev/watchdog', SBD_DEVICE='/dev/sdb1;/dev/sdc1', SBD_WATCHDOG_TIMEOUT="15")
+- mock_update.assert_called_once_with("/etc/sysconfig/sbd")
++ mock_copy.assert_called_once_with("/usr/share/fillup-templates/sysconfig.sbd", "/etc/default/sbd")
++ mock_sysconfig.assert_called_once_with("/etc/default/sbd", SBD_WATCHDOG_DEV='/dev/watchdog', SBD_DEVICE='/dev/sdb1;/dev/sdc1', SBD_WATCHDOG_TIMEOUT="15")
++ mock_update.assert_called_once_with("/etc/default/sbd")
+
+ @mock.patch('crmsh.bootstrap.utils.parse_sysconfig')
+ def test_get_sbd_device_from_config_none(self, mock_parse):
+@@ -525,7 +525,7 @@
+ res = self.sbd_inst._get_sbd_device_from_config()
+ assert res == []
+
+- mock_parse.assert_called_once_with("/etc/sysconfig/sbd")
++ mock_parse.assert_called_once_with("/etc/default/sbd")
+ mock_parse_inst.get.assert_called_once_with("SBD_DEVICE")
+
+ @mock.patch('crmsh.utils.re_split_string')
+@@ -539,7 +539,7 @@
+ res = self.sbd_inst._get_sbd_device_from_config()
+ assert res == ["/dev/sdb1", "/dev/sdc1"]
+
+- mock_parse.assert_called_once_with("/etc/sysconfig/sbd")
++ mock_parse.assert_called_once_with("/etc/default/sbd")
+ mock_parse_inst.get.assert_called_once_with("SBD_DEVICE")
+ mock_split.assert_called_once_with(sbd.SBDManager.PARSE_RE, "/dev/sdb1;/dev/sdc1")
+
+@@ -712,7 +712,7 @@
+ mock_exists.return_value = False
+ self.sbd_inst.join_sbd("alice", "node1")
+ mock_package.assert_called_once_with("sbd")
+- mock_exists.assert_called_once_with("/etc/sysconfig/sbd")
++ mock_exists.assert_called_once_with("/etc/default/sbd")
+ mock_invoke.assert_called_once_with("systemctl disable sbd.service")
+
+ @mock.patch('crmsh.bootstrap.invoke')
+@@ -727,7 +727,7 @@
+ self.sbd_inst.join_sbd("alice", "node1")
+
+ mock_package.assert_called_once_with("sbd")
+- mock_exists.assert_called_once_with("/etc/sysconfig/sbd")
++ mock_exists.assert_called_once_with("/etc/default/sbd")
+ mock_invoke.assert_called_once_with("systemctl disable sbd.service")
+ mock_enabled.assert_called_once_with("sbd.service", "node1")
+
+@@ -751,7 +751,7 @@
+ self.sbd_inst.join_sbd("alice", "node1")
+
+ mock_package.assert_called_once_with("sbd")
+- mock_exists.assert_called_once_with("/etc/sysconfig/sbd")
++ mock_exists.assert_called_once_with("/etc/default/sbd")
+ mock_invoke.assert_called_once_with("systemctl enable sbd.service")
+ mock_get_device.assert_called_once_with()
+ mock_verify.assert_called_once_with(["/dev/sdb1"], ["node1"])
+@@ -781,7 +781,7 @@
+ self.sbd_inst.join_sbd("alice", "node1")
+
+ mock_package.assert_called_once_with("sbd")
+- mock_exists.assert_called_once_with("/etc/sysconfig/sbd")
++ mock_exists.assert_called_once_with("/etc/default/sbd")
+ mock_invoke.assert_called_once_with("systemctl enable sbd.service")
+ mock_get_device.assert_called_once_with()
+ mock_warn.assert_called_once_with("node1")
+--- a/test/unittests/test_ui_cluster.py
++++ b/test/unittests/test_ui_cluster.py
+@@ -44,11 +44,13 @@
+ mock_qdevice_configured.return_value = False
+ context_inst = mock.Mock()
+ mock_parse_nodes.return_value = ["node1", "node2"]
+- mock_active.side_effect = [True, True]
++ mock_active.side_effect = [True, True, True, True]
+ self.ui_cluster_inst.do_start(context_inst, "node1", "node2")
+ mock_parse_nodes.assert_called_once_with(context_inst, "node1", "node2")
+ mock_active.assert_has_calls([
++ mock.call("corosync.service", remote_addr="node1"),
+ mock.call("pacemaker.service", remote_addr="node1"),
++ mock.call("corosync.service", remote_addr="node2"),
+ mock.call("pacemaker.service", remote_addr="node2")
+ ])
+ mock_info.assert_has_calls([
+@@ -67,12 +69,13 @@
+ context_inst = mock.Mock()
+ mock_start_pacemaker.return_value = ["node1"]
+ mock_parse_nodes.return_value = ["node1"]
+- mock_active.side_effect = [False, False]
++ mock_active.side_effect = [False, False, False]
+ mock_qdevice_configured.return_value = True
+
+ self.ui_cluster_inst.do_start(context_inst, "node1")
+
+ mock_active.assert_has_calls([
++ mock.call("corosync.service", remote_addr="node1"),
+ mock.call("pacemaker.service", remote_addr="node1"),
+ mock.call("corosync-qdevice.service", remote_addr="node1")
+ ])
+--- a/test/unittests/test_bootstrap.py
++++ b/test/unittests/test_bootstrap.py
+@@ -1760,7 +1760,7 @@
+ bootstrap.rm_configuration_files()
+ mock_run.assert_has_calls([
+ mock.call('rm -f file1 file2', None),
+- mock.call('cp /usr/share/fillup-templates/sysconfig.sbd /etc/sysconfig/sbd', None)
++ mock.call('cp /usr/share/fillup-templates/sysconfig.sbd /etc/default/sbd', None)
+ ])
+
+ @mock.patch('crmsh.utils.get_iplist_from_name')
+--- a/test/cibtests/001.exp.xml
++++ b/test/cibtests/001.exp.xml
+@@ -9,6 +9,9 @@
+ <resources>
+ <primitive id="rsc_dummy" class="ocf" provider="heartbeat" type="Dummy">
+ <operations>
++ <op name="monitor" timeout="20s" interval="10s" id="rsc_dummy-monitor-10s"/>
++ <op name="start" timeout="20s" interval="0s" id="rsc_dummy-start-0s"/>
++ <op name="stop" timeout="20s" interval="0s" id="rsc_dummy-stop-0s"/>
+ <op name="monitor" interval="30" id="rsc_dummy-monitor-30"/>
+ </operations>
+ </primitive>
+--- a/test/cibtests/002.exp.xml
++++ b/test/cibtests/002.exp.xml
+@@ -13,6 +13,11 @@
+ <nvpair name="interleave" value="true" id="testfs-clone-meta_attributes-interleave"/>
+ </meta_attributes>
+ <primitive id="testfs" class="ocf" provider="heartbeat" type="Dummy">
++ <operations>
++ <op name="monitor" timeout="20s" interval="10s" id="testfs-monitor-10s"/>
++ <op name="start" timeout="20s" interval="0s" id="testfs-start-0s"/>
++ <op name="stop" timeout="20s" interval="0s" id="testfs-stop-0s"/>
++ </operations>
+ <instance_attributes id="testfs-instance_attributes">
+ <nvpair name="fake" value="1" id="testfs-instance_attributes-fake"/>
+ </instance_attributes>
+--- a/test/cibtests/003.exp.xml
++++ b/test/cibtests/003.exp.xml
+@@ -14,6 +14,11 @@
+ <nvpair id="testfs-clone-meta_attributes-target-role" name="target-role" value="Stopped"/>
+ </meta_attributes>
+ <primitive id="testfs" class="ocf" provider="heartbeat" type="Dummy">
++ <operations>
++ <op name="monitor" timeout="20s" interval="10s" id="testfs-monitor-10s"/>
++ <op name="start" timeout="20s" interval="0s" id="testfs-start-0s"/>
++ <op name="stop" timeout="20s" interval="0s" id="testfs-stop-0s"/>
++ </operations>
+ <instance_attributes id="testfs-instance_attributes">
+ <nvpair name="fake" value="2" id="testfs-instance_attributes-fake"/>
+ </instance_attributes>
+--- a/test/cibtests/004.exp.xml
++++ b/test/cibtests/004.exp.xml
+@@ -14,6 +14,11 @@
+ <nvpair id="testfs-clone-meta_attributes-target-role" name="target-role" value="Started"/>
+ </meta_attributes>
+ <primitive id="testfs" class="ocf" provider="heartbeat" type="Dummy">
++ <operations>
++ <op name="monitor" timeout="20s" interval="10s" id="testfs-monitor-10s"/>
++ <op name="start" timeout="20s" interval="0s" id="testfs-start-0s"/>
++ <op name="stop" timeout="20s" interval="0s" id="testfs-stop-0s"/>
++ </operations>
+ <instance_attributes id="testfs-instance_attributes">
+ <nvpair name="fake" value="hello" id="testfs-instance_attributes-fake"/>
+ </instance_attributes>
diff --git a/debian/patches/0016-Fix-python2-calls.patch b/debian/patches/0016-Fix-python2-calls.patch
new file mode 100644
index 0000000..568ccd6
--- /dev/null
+++ b/debian/patches/0016-Fix-python2-calls.patch
@@ -0,0 +1,138 @@
+Description: Build using only python 3
+Author: Valentin Vidic <vvidic@debian.org>
+Last-Update: 2019-08-16
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/doc/website-v1/Makefile
++++ b/doc/website-v1/Makefile
+@@ -54,6 +54,7 @@
+ XDGOPEN := xdg-open
+ NEWS := $(wildcard news/*.adoc)
+ NEWSDOC := $(patsubst %.adoc,gen/%/index.html,$(NEWS))
++PYTHON := python3
+
+ .PHONY: all clean deploy open
+
+@@ -62,33 +63,33 @@
+ gen/index.html: index.adoc $(CRMCONF)
+ @mkdir -p $(dir $@)
+ @$(ASCIIDOC) --unsafe -b html5 -a icons -a iconsdir=/img/icons -f $(CRMCONF) -o $@ $<
+- @python ./postprocess.py -o $@ $<
++ @$(PYTHON) ./postprocess.py -o $@ $<
+
+ gen/%/index.html: %.adoc $(CRMCONF)
+ @mkdir -p $(dir $@)
+ @$(ASCIIDOC) --unsafe -b html5 -a icons -a iconsdir=/img/icons -f $(CRMCONF) -o $@ $<
+- @python ./postprocess.py -o $@ $<
++ @$(PYTHON) ./postprocess.py -o $@ $<
+
+ gen/history-guide/index.html: $(HISTORY_LISTINGS)
+
+ gen/man/index.html: ../crm.8.adoc $(CRMCONF)
+ @mkdir -p $(dir $@)
+ @$(ASCIIDOC) --unsafe -b html5 -f $(CRMCONF) -o $@ $<
+- @python ./postprocess.py -o $@ $<
++ @$(PYTHON) ./postprocess.py -o $@ $<
+
+ gen/404.html: 404.adoc $(CRMCONF)
+ @mkdir -p $(dir $@)
+ @$(ASCIIDOC) --unsafe -b html5 -f $(CRMCONF) -o $@ $<
+- @python ./postprocess.py -o $@ $<
++ @$(PYTHON) ./postprocess.py -o $@ $<
+
+ news.adoc: $(NEWS) $(CRMCONF)
+ @echo "news:" $(NEWS)
+- python ./make-news.py $@ $(NEWS)
++ $(PYTHON) ./make-news.py $@ $(NEWS)
+
+ gen/news/index.html: news.adoc
+ @mkdir -p $(dir $@)
+ $(ASCIIDOC) --unsafe -b html5 -f $(CRMCONF) -o $@ $<
+- @python ./postprocess.py -o $@ $<
++ @$(PYTHON) ./postprocess.py -o $@ $<
+
+ gen/css/%.css: css/%.css
+ @mkdir -p gen/css
+@@ -127,7 +128,7 @@
+
+ gen/atom.xml: $(NEWSDOC)
+ @echo "atom:" $(NEWSDOC)
+- python ./make-news.py gen/atom.xml $(NEWS)
++ $(PYTHON) ./make-news.py gen/atom.xml $(NEWS)
+
+ site: gen/atom.xml gen/index.html gen/404.html gen/news/index.html gen/man/index.html $(TGT) $(CSS) $(IMG) $(FONTS) $(NEWSDOC)
+ @which dos2unix >/dev/null && find gen -name "*.html" -type f -exec dos2unix {} \;
+--- a/doc/website-v1/postprocess.py
++++ b/doc/website-v1/postprocess.py
+@@ -48,7 +48,7 @@
+ def generate_toc(infile, outfile, debug):
+
+ if debug:
+- print "Infile:", infile
++ print("Infile:", infile)
+ toc = read_toc_data(infile, debug)
+ '''
+ toc_data = []
+@@ -57,7 +57,7 @@
+ m = section.match(line)
+ if m:
+ if debug:
+- print "toc_data: %s" % str(((m.group('depth'), m.group('text'), m.group('id'))))
++ print("toc_data: %s" % str(((m.group('depth'), m.group('text'), m.group('id')))))
+ toc_data.append((m.group('depth'), m.group('text'), m.group('id')))
+
+ toc = ''
+@@ -73,11 +73,11 @@
+ # Write TOC to outfile
+ if outfile:
+ if debug:
+- print "Writing TOC:"
+- print "----"
+- print toc
+- print "----"
+- print "Outfile:", outfile
++ print("Writing TOC:")
++ print("----")
++ print(toc)
++ print("----")
++ print("Outfile:", outfile)
+ fil = open(outfile)
+ f = fil.readlines()
+ fil.close()
+@@ -96,14 +96,14 @@
+ m = section.match(line)
+ if m:
+ if debug:
+- print "toc_data: %s" % str(((m.group('depth'), m.group('text'), m.group('id'))))
++ print("toc_data: %s" % str(((m.group('depth'), m.group('text'), m.group('id')))))
+ toc_data.append((m.group('depth'), m.group('text'), m.group('id')))
+
+ toc = ''
+ if len(toc_data) > 0:
+ toc = '<div id="toc">\n'
+ for depth, text, link in toc_data:
+- if depth >= 2 and link is not None:
++ if int(depth) >= 2 and link is not None:
+ toc += '<div class="toclevel%s"><a href="#%s">%s</a></div>\n' % (
+ int(depth) - 1, link, text)
+ toc += '</div>\n'
+@@ -126,7 +126,7 @@
+ debug = args.debug
+ outfile = args.output
+ infile = args.input
+- print "+ %s -> %s" % (infile, outfile)
++ print("+ %s -> %s" % (infile, outfile))
+ gen = False
+ for tocpage in TOC_PAGES:
+ if not gen and outfile.endswith(tocpage):
+--- a/doc/website-v1/make-news.py
++++ b/doc/website-v1/make-news.py
+@@ -63,7 +63,7 @@
+ raise ValueError("Missing date")
+
+ def atom_id(self):
+- return root_id + '::' + hashlib.sha1(self.filename).hexdigest()
++ return root_id + '::' + hashlib.sha1(self.filename.encode('utf-8')).hexdigest()
+
+ def atom_date(self):
+ return self.date.replace(' ', 'T') + ':00' + time.tzname[0]
diff --git a/debian/patches/0017-Fix-profiles-adoc.patch b/debian/patches/0017-Fix-profiles-adoc.patch
new file mode 100644
index 0000000..ece2773
--- /dev/null
+++ b/debian/patches/0017-Fix-profiles-adoc.patch
@@ -0,0 +1,17 @@
+Description: Skip building profiles as a separate document
+ It is included in crm(8) already.
+Author: Valentin Vidic <vvidic@debian.org>
+Last-Update: 2022-05-28
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -29,7 +29,7 @@
+ contribdir = $(docdir)/contrib
+ contrib_DATA = contrib/pcmk.vim contrib/README.vimsyntax
+ helpdir = $(datadir)/$(PACKAGE)
+-asciiman = doc/crm.8.adoc doc/crmsh_crm_report.8.adoc doc/profiles.adoc
++asciiman = doc/crm.8.adoc doc/crmsh_crm_report.8.adoc
+ help_DATA = doc/crm.8.adoc
+
+ generated_docs =
diff --git a/debian/patches/0018-Fix-python3-install.patch b/debian/patches/0018-Fix-python3-install.patch
new file mode 100644
index 0000000..de1c33e
--- /dev/null
+++ b/debian/patches/0018-Fix-python3-install.patch
@@ -0,0 +1,16 @@
+Description: Fix build failure with new version of setuptools
+ Files get installed in /usr/local.
+Author: Valentin Vidic <vvidic@debian.org>
+Last-Update: 2022-10-15
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -69,6 +69,7 @@
+ $(PYTHON) $(srcdir)/setup.py install \
+ --root $(DESTDIR)/// \
+ $(python_prefix) \
++ --install-layout=deb \
+ --record $(DESTDIR)$(pkgpythondir)/install_files.txt \
+ --verbose
+ $(INSTALL) -d -m 770 $(DESTDIR)$(CRM_CACHE_DIR)
diff --git a/debian/patches/0019-Remove-news-adoc.patch b/debian/patches/0019-Remove-news-adoc.patch
new file mode 100644
index 0000000..be0fed7
--- /dev/null
+++ b/debian/patches/0019-Remove-news-adoc.patch
@@ -0,0 +1,34 @@
+Description: Fix rebuild failure due to generated files
+Author: Valentin Vidic <vvidic@debian.org>
+Last-Update: 2023-10-10
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/doc/website-v1/news.adoc
++++ /dev/null
+@@ -1,26 +0,0 @@
+-= News
+-
+-link:/news/2017-01-31-release-3_0_0[2017-01-31 10:00]
+-
+-:leveloffset: 1
+-
+-include::news/2017-01-31-release-3_0_0.adoc[]
+-
+-:leveloffset: 0
+-
+-''''
+-* link:/news/2016-09-05-release-2_2_2[2016-09-05 19:00 Releasing crmsh version 2.2.2]
+-* link:/news/2016-09-02-release-2_3_1[2016-09-02 10:00 Releasing crmsh version 2.3.1]
+-* link:/news/2016-09-01-release-2_1_7[2016-09-01 09:00 Announcing crmsh stable release 2.1.7]
+-* link:/news/2016-08-12-release-2_3_0[2016-08-12 10:30 Releasing crmsh version 2.3.0]
+-* link:/news/2016-04-28-release-2_2_1[2016-04-28 01:00 crmsh 2.2.1 and 2.1.6 are released]
+-* link:/news/2016-01-15-release-2_2_0[2016-01-15 15:00 crmsh 2.2.0 is released]
+-* link:/news/2016-01-12-release-2_1_5[2016-01-12 10:00 Announcing crmsh stable release 2.1.5]
+-* link:/news/2015-05-25-getting-started-jp[2015-05-25 13:30 Getting Started translated to Japanese]
+-* link:/news/2015-05-13-release-2_1_4[2015-05-13 15:30 Announcing crmsh stable release 2.1.4]
+-* link:/news/2015-04-10-release-2_1_3[2015-04-10 12:30 Announcing crmsh stable release 2.1.3]
+-* link:/news/2015-01-26-release-2_1_2[2015-01-26 11:05 Announcing crmsh release 2.1.2]
+-* link:/news/2014-10-28-release-2_1_1[2014-10-29 00:20 Announcing crmsh release 2.1.1]
+-* link:/news/2014-06-30-release-2_1[2014-06-30 09:00 Announcing crmsh release 2.1]
+-
+-link:https://savannah.nongnu.org/news/?group_id=10890[Old News Archive]
diff --git a/debian/patches/0020-Replace-distutils.patch b/debian/patches/0020-Replace-distutils.patch
new file mode 100644
index 0000000..fd5cfb3
--- /dev/null
+++ b/debian/patches/0020-Replace-distutils.patch
@@ -0,0 +1,75 @@
+Description: Fix build with python 3.12
+Author: Valentin Vidic <vvidic@debian.org>
+Last-Update: 2024-03-04
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/crmsh/ra.py
++++ b/crmsh/ra.py
+@@ -50,15 +50,15 @@
+
+ @utils.memoize
+ def can_use_lrmadmin():
+- from distutils import version
++ from packaging.version import Version
+ # after this glue release all users can get meta-data and
+ # similar from lrmd
+ minimum_glue = "1.0.10"
+ _rc, glue_ver = ShellUtils().get_stdout("%s -v" % lrmadmin_prog, stderr_on=False)
+ if not glue_ver: # lrmadmin probably not found
+ return False
+- v_min = version.LooseVersion(minimum_glue)
+- v_this = version.LooseVersion(glue_ver)
++ v_min = Version(minimum_glue)
++ v_this = Version(glue_ver)
+ if v_this < v_min:
+ return False
+ if userdir.getuser() not in ("root", config.path.crm_daemon_user):
+--- a/crmsh/utils.py
++++ b/crmsh/utils.py
+@@ -37,7 +37,7 @@
+ from . import constants
+ from . import options
+ from . import term
+-from distutils.version import LooseVersion
++from packaging import version
+ from .constants import SSH_OPTION
+ from . import log
+ from .prun import prun
+@@ -1632,8 +1632,15 @@
+ return val_l
+
+
+-def is_larger_than_min_version(version, min_version):
+- return LooseVersion(version) >= LooseVersion(min_version)
++def is_larger_than_min_version(this_version, min_version):
++ version_re = re.compile(version.VERSION_PATTERN, re.VERBOSE | re.IGNORECASE)
++ match1 = version_re.search(this_version)
++ if not match1:
++ raise InvalidVersion(f"Invalid version: '{this_version}'")
++ match2 = version_re.search(min_version)
++ if not match2:
++ raise InvalidVersion(f"Invalid version: '{min_version}'")
++ return version.parse(match1.group(0)) >= version.parse(match2.group(0))
+
+
+ def is_min_pcmk_ver(min_ver, cib_f=None):
+--- a/test/unittests/test_utils.py
++++ b/test/unittests/test_utils.py
+@@ -7,7 +7,7 @@
+ import os
+ import socket
+ import re
+-import imp
++import importlib
+ import subprocess
+ import unittest
+ import pytest
+@@ -24,7 +24,7 @@
+ utils._ip_for_cloud = None
+ # Mock memoize method and reload the module under test later with imp
+ mock.patch('crmsh.utils.memoize', lambda x: x).start()
+- imp.reload(utils)
++ importlib.reload(utils)
+
+
+ @mock.patch("crmsh.sh.ShellUtils.get_stdout_stderr")
diff --git a/debian/patches/0021-Fix-bootstrap-bash.patch b/debian/patches/0021-Fix-bootstrap-bash.patch
new file mode 100644
index 0000000..943aeb9
--- /dev/null
+++ b/debian/patches/0021-Fix-bootstrap-bash.patch
@@ -0,0 +1,25 @@
+Description: Fix bootstrap with dash
+Author: Valentin Vidic <vvidic@debian.org>
+Last-Update: 2024-02-17
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/crmsh/ssh_key.py
++++ b/crmsh/ssh_key.py
+@@ -235,7 +235,7 @@
+ ssh-keygen -t rsa -f ~/.ssh/id_rsa -q -C "Cluster internal on $(hostname)" -N '' <> /dev/null
+ echo 'GENERATED=1'
+ fi
+-for file in ~/.ssh/id_{{{pattern}}}; do
++for file in {pattern}; do
+ if [ -f "$file" ]; then
+ if ! [ -f "$file".pub ]; then
+ ssh-keygen -y -f "$file" > "$file".pub
+@@ -245,7 +245,7 @@
+ done
+ '''.format(
+ condition=' -o '.join([f'-f ~/.ssh/id_{t}' for t in self.KNOWN_KEY_TYPES]),
+- pattern=','.join(self.KNOWN_KEY_TYPES),
++ pattern=' '.join([f'~/.ssh/id_{t}' for t in self.KNOWN_KEY_TYPES]),
+ )
+ result = self.cluster_shell.subprocess_run_without_input(
+ host, user,
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..b77d82f
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,17 @@
+0003-Add-remote-resource-to-local-cache.patch
+0004-Fix-privacy-breach-generic-caused-by-footer-template.patch
+0005-Fix-privacy-breach-generic-caused-by-atom-xml-templa.patch
+0006-Fix-privacy-breach-generic-caused-by-youtube-iframe.patch
+0007-pygmentize-lexer.patch
+0010-Fix-package-management.patch
+0011-Fix-scripts-init.patch
+0012-Fix-crm-history.patch
+0013-Fix-cluster-bootstrap.patch
+0014-Fix-cluster-stop-start.patch
+0015-Fix-testsuite-errors.patch
+0016-Fix-python2-calls.patch
+0017-Fix-profiles-adoc.patch
+0018-Fix-python3-install.patch
+0019-Remove-news-adoc.patch
+0020-Replace-distutils.patch
+0021-Fix-bootstrap-bash.patch