diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/.gitignore b/.gitignore index 44c2524..ec4bfb1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ /corosync-qdevice-2.93.0.tar.gz /corosync-qdevice-3.0.0.tar.gz /corosync-qdevice-3.0.1.tar.gz +/corosync-qdevice-3.0.2.tar.gz +/corosync-qdevice-3.0.3.tar.gz +/corosync-qdevice-3.0.4.tar.gz diff --git a/corosync-qdevice.rpmlintrc b/corosync-qdevice.rpmlintrc new file mode 100644 index 0000000..ff8083c --- /dev/null +++ b/corosync-qdevice.rpmlintrc @@ -0,0 +1,20 @@ +# qdevice coroqnetd group directories +addFilter(r'corosync-qdevice\.[^:]+: (E|W): non-standard-dir-perm /etc/corosync/qdevice/net 770') +addFilter(r'corosync-qdevice\.[^:]+: (E|W): dir-or-file-in-var-run /var/run/corosync-qdevice') +addFilter(r'corosync-qdevice\.[^:]+: (E|W): non-standard-dir-perm /var/run/corosync-qdevice 770') + +# qnetd coroqnetd group directories +addFilter(r'corosync-qnetd\.[^:]+: (E|W): non-standard-(u|g)id /etc/corosync/qnetd coroqnetd') +addFilter(r'corosync-qnetd\.[^:]+: (E|W): non-standard-(u|g)id /var/run/corosync-qnetd coroqnetd') +addFilter(r'corosync-qnetd\.[^:]+: (E|W): non-standard-dir-perm /etc/corosync/qnetd 770') +addFilter(r'corosync-qnetd\.[^:]+: (E|W): dir-or-file-in-var-run /var/run/corosync-qnetd') +addFilter(r'corosync-qnetd\.[^:]+: (E|W): non-standard-dir-perm /var/run/corosync-qnetd 770') + +# Empty %postun +addFilter(r'W: empty-%postun') + +# Spelling error init +addFilter(r'W: spelling-error %description -l en_US init') + +# No docs for qdevice devel sub-package +addFilter(r'corosync-qdevice-devel\.[^:]+: W: no-documentation') diff --git a/corosync-qdevice.spec b/corosync-qdevice.spec index 0870582..21f7ae7 100644 --- a/corosync-qdevice.spec +++ b/corosync-qdevice.spec @@ -3,32 +3,23 @@ # to disable or enable specific features %bcond_without userflags %bcond_with runautogen -%bcond_without systemd - -%global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}} -%global gittarver %{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}} Name: corosync-qdevice Summary: The Corosync Cluster Engine Qdevice -Version: 3.0.1 -Release: 1%{?gitver}%{?dist} -License: BSD +Version: 3.0.4 +Release: 1%{?dist} +License: BSD-3-Clause URL: https://github.com/corosync/corosync-qdevice -Source0: https://github.com/corosync/corosync-qdevice/releases/download/v%{version}%{?gittarver}/%{name}-%{version}%{?gittarver}.tar.gz +Source0: https://github.com/corosync/corosync-qdevice/releases/download/v%{version}/%{name}-%{version}.tar.gz # Runtime bits Requires: corosync >= 2.4.0 Requires: corosynclib >= 2.4.0 Requires: nss-tools -%if %{with systemd} %{?systemd_requires} BuildRequires: systemd BuildRequires: systemd-devel -%else -Requires(post): /sbin/chkconfig -Requires(preun): /sbin/chkconfig -%endif # Build bits BuildRequires: gcc @@ -41,9 +32,11 @@ BuildRequires: nss-devel %if %{with runautogen} BuildRequires: autoconf automake libtool %endif +BuildRequires: make +BuildRequires: git %prep -%setup -q -n %{name}-%{version}%{?gittarver} +%autosetup -S git_am %build %if %{with runautogen} @@ -54,19 +47,17 @@ BuildRequires: autoconf automake libtool %if %{with userflags} --enable-user-flags \ %endif -%if %{with systemd} --enable-systemd \ -%endif --enable-qdevices \ --enable-qnetd \ --with-initddir=%{_initrddir} \ --with-systemddir=%{_unitdir} \ --docdir=%{_docdir} -make %{_smp_mflags} +%make_build %install -make install DESTDIR=%{buildroot} +%make_install ## tree fixup # drop docs and html docs for now @@ -79,41 +70,23 @@ install -p -m 644 init/corosync-qdevice.sysconfig.example \ install -p -m 644 init/corosync-qnetd.sysconfig.example \ %{buildroot}%{_sysconfdir}/sysconfig/corosync-qnetd -%if %{with systemd} sed -i -e 's/^#User=/User=/' \ %{buildroot}%{_unitdir}/corosync-qnetd.service -%else -sed -i -e 's/^COROSYNC_QNETD_RUNAS=""$/COROSYNC_QNETD_RUNAS="coroqnetd"/' \ - %{buildroot}%{_sysconfdir}/sysconfig/corosync-qnetd -%endif + +install -m0644 -D init/corosync-qnetd.sysusers.conf.example %{buildroot}%{_sysusersdir}/corosync-qnetd.conf %description This package contains the Corosync Cluster Engine Qdevice, script for creating NSS certificates and an init script. %post -%if %{with systemd} && 0%{?systemd_post:1} %systemd_post corosync-qdevice.service -%else -if [ $1 -eq 1 ]; then - /sbin/chkconfig --add corosync-qdevice || : -fi -%endif %preun -%if %{with systemd} && 0%{?systemd_preun:1} %systemd_preun corosync-qdevice.service -%else -if [ $1 -eq 0 ]; then - /sbin/service corosync-qdevice stop &>/dev/null || : - /sbin/chkconfig --del corosync-qdevice || : -fi -%endif %postun -%if %{with systemd} && 0%{?systemd_postun:1} %systemd_postun corosync-qdevice.service -%endif %files %license LICENSE @@ -124,11 +97,7 @@ fi %{_sbindir}/corosync-qdevice-net-certutil %{_sbindir}/corosync-qdevice-tool %config(noreplace) %{_sysconfdir}/sysconfig/corosync-qdevice -%if %{with systemd} %{_unitdir}/corosync-qdevice.service -%else -%{_initrddir}/corosync-qdevice -%endif %{_mandir}/man8/corosync-qdevice-tool.8* %{_mandir}/man8/corosync-qdevice-net-certutil.8* %{_mandir}/man8/corosync-qdevice.8* @@ -148,45 +117,22 @@ The Corosync Cluster Engine Qdevice %package -n corosync-qnetd Summary: The Corosync Cluster Engine Qdevice Network Daemon Requires: nss-tools -Requires(pre): shadow-utils -%if %{with systemd} %{?systemd_requires} -%endif %description -n corosync-qnetd This package contains the Corosync Cluster Engine Qdevice Network Daemon, script for creating NSS certificates and an init script. -%pre -n corosync-qnetd -getent group coroqnetd >/dev/null || groupadd -r coroqnetd -getent passwd coroqnetd >/dev/null || \ - useradd -r -g coroqnetd -d / -s /sbin/nologin -c "User for corosync-qnetd" coroqnetd -exit 0 %post -n corosync-qnetd -%if %{with systemd} && 0%{?systemd_post:1} %systemd_post corosync-qnetd.service -%else -if [ $1 -eq 1 ]; then - /sbin/chkconfig --add corosync-qnetd || : -fi -%endif %preun -n corosync-qnetd -%if %{with systemd} && 0%{?systemd_preun:1} %systemd_preun corosync-qnetd.service -%else -if [ $1 -eq 0 ]; then - /sbin/service corosync-qnetd stop &>/dev/null || : - /sbin/chkconfig --del corosync-qnetd || : -fi -%endif %postun -n corosync-qnetd -%if %{with systemd} && 0%{?systemd_postun:1} %systemd_postun corosync-qnetd.service -%endif %files -n corosync-qnetd %license LICENSE @@ -196,19 +142,82 @@ fi %{_bindir}/corosync-qnetd-certutil %{_bindir}/corosync-qnetd-tool %config(noreplace) %{_sysconfdir}/sysconfig/corosync-qnetd -%if %{with systemd} %{_unitdir}/corosync-qnetd.service -%else -%{_initrddir}/corosync-qnetd -%endif %{_mandir}/man8/corosync-qnetd-tool.8* %{_mandir}/man8/corosync-qnetd-certutil.8* %{_mandir}/man8/corosync-qnetd.8* +%{_sysusersdir}/corosync-qnetd.conf %changelog +* Tue Nov 25 2025 Jan Friesse - 3.0.4-1 +- New upstream release + +* Wed Jul 23 2025 Fedora Release Engineering - 3.0.3-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Tue Feb 11 2025 Jan Friesse - 3.0.3-9 +- Change sysusers.d config file name to corosync-qnetd.conf +- Remove support for non-systemd builds + +* Tue Feb 11 2025 Zbigniew Jędrzejewski-Szmek - 3.0.3-8 +- Add sysusers.d config file to allow rpm to create users/groups automatically + +* Thu Jan 16 2025 Fedora Release Engineering - 3.0.3-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Wed Jul 17 2024 Fedora Release Engineering - 3.0.3-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Wed Jan 24 2024 Fedora Release Engineering - 3.0.3-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 3.0.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Wed Jul 19 2023 Fedora Release Engineering - 3.0.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Tue Jun 06 2023 Jan Friesse - 3.0.3-2 +- migrated to SPDX license + +* Wed Mar 22 2023 Jan Friesse - 3.0.3-1 +- New upstream release + +* Thu Jan 19 2023 Fedora Release Engineering - 3.0.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Thu Nov 03 2022 Jan Friesse - 3.0.2-1 +- New upstream release + +* Wed Jul 20 2022 Fedora Release Engineering - 3.0.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Wed Jan 19 2022 Fedora Release Engineering - 3.0.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Tue Jan 26 2021 Fedora Release Engineering - 3.0.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Mon Nov 23 2020 Jan Friesse - 3.0.1-1 - New upstream release +* Mon Jul 27 2020 Fedora Release Engineering - 3.0.0-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Wed Jul 22 2020 Jan Friesse - 3.0.0-9 +- Use make macros +- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro + +* Wed May 13 2020 Jan Friesse - 3.0.0-8 +- Really rebuild for the new libqb + +* Wed May 13 2020 Jan Friesse - 3.0.0-7 +- Rebuild for new libqb + +* Thu Mar 26 2020 Jan Friesse - 3.0.0-6 +- Add CI tests +- Enable gating + * Tue Jan 28 2020 Fedora Release Engineering - 3.0.0-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild diff --git a/gating.yaml b/gating.yaml new file mode 100644 index 0000000..f075ad7 --- /dev/null +++ b/gating.yaml @@ -0,0 +1,15 @@ +--- !Policy +product_versions: + - fedora-* +decision_context: bodhi_update_push_testing +subject_type: koji_build +rules: + - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional} + +--- !Policy +product_versions: + - fedora-* +decision_context: bodhi_update_push_stable +subject_type: koji_build +rules: + - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional} diff --git a/sources b/sources index 90426a1..2dd25f0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (corosync-qdevice-3.0.1.tar.gz) = 677aff51b5b3cae693ccf342494077cb5ee5ba16ff71c6d8da17f5ab54bc31e0df5c8e0fd4292125c0bffeaa25371d58360a7ec8b122534f92818d3658b46c98 +SHA512 (corosync-qdevice-3.0.4.tar.gz) = a7e2e1fcab699c6deb0ae01725df6a1d3870c0f874b7dff96f657ac3e0d9fadb682ae145d6a9d29c592ca8f34ad12b8523c6adf9b14b0a01e59d998d8cb8c25f diff --git a/tests/plan.fmf b/tests/plan.fmf new file mode 100644 index 0000000..146fa12 --- /dev/null +++ b/tests/plan.fmf @@ -0,0 +1,11 @@ +summary: Run all smoke tests +discover: + how: fmf +execute: + how: tmt +prepare: + how: install + package: + - iproute + - corosync-qdevice + - corosync-qnetd diff --git a/tests/smoke/main.fmf b/tests/smoke/main.fmf new file mode 100644 index 0000000..c431594 --- /dev/null +++ b/tests/smoke/main.fmf @@ -0,0 +1,2 @@ +summary: Basic smoke test +test: ./runtest.sh diff --git a/tests/smoke/runtest.sh b/tests/smoke/runtest.sh new file mode 100755 index 0000000..efdb5dc --- /dev/null +++ b/tests/smoke/runtest.sh @@ -0,0 +1,348 @@ +#!/bin/bash + +# This file was autogenerated at 2019-05-13T13:43:38+02:00 from 90bd97ada89befa1a63133335a419ad7311c3d75 + +# Copyright (c) 2019, Red Hat, Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND RED HAT, INC. DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RED HAT, INC. BE LIABLE +# FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# Author: Jan Friesse + + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# !!! Script overwrites corosync.conf, authkey and qdevice/qnetd certificates !!! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +# Home https://github.com/jfriesse/csts/tree/master/smoke + +# -e is really important +set -xe +set -o pipefail + +# Variables changing test behavior +PREFIX="/" + +COROSYNC_SYSCONFD="${PREFIX}etc/corosync" +COROSYNC_CONF="${COROSYNC_SYSCONFD}/corosync.conf" +COROSYNC_AUTHKEY="${COROSYNC_SYSCONFD}/authkey" +COROSYNC_CLUSTER_NAME="smoketestcluster" + +TOKEN_TIMEOUT=1000 +MAX_REPEATS=60 + +#################### +# Helper functions # +#################### +get_ip() { + ip_res=$(ip route get 8.8.8.8) + # Format is "8.8.8.8 via ROUTE_IPADDR dev DEV src IPADDR uid NUMBER" + # Remove everything up to "src " and then everything after " " + addr=${ip_res##*src } + addr=${addr%% *} + + echo "$addr" +} + +# generate_corosync_conf crypto [token] [qdevice] +# crypto can be on or off +# when token is defined it is used for token timeout +# when qdevice is set to on qdevice section is created and second node is added +generate_corosync_conf() { + case "$1" in + "on") + cipher="aes256" + hash="sha256" + ;; + "off") + cipher="none" + hash="none" + ;; + *) + # Unknown crypto + exit 1 + esac + + token=$TOKEN_TIMEOUT + if [ ! -z "$2" ];then + token="$2" + fi + qdevice="$3" + true_command=`which true` + +cat << _EOF_ + totem { + version: 2 + cluster_name: $COROSYNC_CLUSTER_NAME + transport: knet + crypto_cipher: $cipher + crypto_hash: $hash + token: $token + } + + logging { + to_logfile: yes + logfile: /var/log/cluster/corosync.log + to_syslog: yes + } + + quorum { + provider: corosync_votequorum +_EOF_ + + if [ "$qdevice" == "on" ];then +cat << _EOF_ + device { + votes: 1 + model: net + net { + host: $LOCAL_IP + algorithm: ffsplit + } + heuristics { + mode: sync + exec_true: $true_command + } + } +_EOF_ + fi + +cat << _EOF_ + } + + nodelist { + node { + nodeid: 1 + ring0_addr: $LOCAL_IP + } +_EOF_ + + if [ "$qdevice" == "on" ];then +cat << _EOF_ + node { + nodeid: 2 + ring0_addr: 192.0.2.2 + } +_EOF_ + fi + +cat << _EOF_ + } +_EOF_ +} + +# service_start service +service_start() { + # service service must be inactive + systemctl is-active "$1" && exit 1 || true + + systemctl start "$1" + + systemctl is-active "$1" +} + +# service_stop service +service_stop() { + systemctl is-active "$1" || exit 1 + + systemctl stop "$1" + + systemctl is-active "$1" && exit 1 || true +} + +###################### +# Computed variables # +###################### +LOCAL_IP=$(get_ip) + +################## +# C test sources # +################## + +# Test sources are encoded as a base64 string and piped to base64 to store them in /tmp +################## +# Test functions # +################## +test_corosync_qdevice_h() { + # Check that corosync-qdevice(-tool) binary exists and -h returns help text + res=`corosync-qdevice -h || true` + [ "$res" != "${res/usage/}" ] + res=`corosync-qdevice-tool -h || true` + [ "$res" != "${res/usage/}" ] +} + +test_corosync_qnetd_h() { + # Check that corosync-qnetd(-tool) binary exists and -h returns help text + res=`corosync-qnetd -h || true` + [ "$res" != "${res/usage/}" ] + res=`corosync-qnetd-tool -h || true` + [ "$res" != "${res/usage/}" ] +} + +test_crt_creation() { + # Erase old certificates + rm -rf "$COROSYNC_SYSCONFD/qdevice/net/nssdb" + rm -rf "$COROSYNC_SYSCONFD/qnetd/nssdb" + + corosync-qnetd-certutil -i + corosync-qdevice-net-certutil -i -c "$COROSYNC_SYSCONFD/qnetd/nssdb/qnetd-cacert.crt" + corosync-qdevice-net-certutil -r -n "$COROSYNC_CLUSTER_NAME" + corosync-qnetd-certutil -s -c "$COROSYNC_SYSCONFD/qdevice/net/nssdb/qdevice-net-node.crq" -n "$COROSYNC_CLUSTER_NAME" + corosync-qdevice-net-certutil -M -c "$COROSYNC_SYSCONFD/qnetd/nssdb/cluster-$COROSYNC_CLUSTER_NAME.crt" +} + +test_qnetd_start() { + service_start "corosync-qnetd" +} + +test_qdevice_start() { + service_start "corosync-qdevice" +} + +test_corosync_start() { + generate_corosync_conf "off" "" "on" > "$COROSYNC_CONF" + cat "$COROSYNC_CONF" + + service_start "corosync" +} + +test_qdevice_stop() { + service_stop "corosync-qdevice" +} + +test_qnetd_stop() { + service_stop "corosync-qnetd" +} + +test_corosync_stop() { + service_stop "corosync" +} + +# test_corosync_quorumtool quorate +# quorate can be yes or no +test_corosync_quorumtool() { + quorumtool_res_file=`mktemp` + # This is already fixed in upstream db38e3958c4f88d5d06e8f7c83d6d90334d9fbd2 + (corosync-quorumtool -ips || true) | tee "$quorumtool_res_file" + + # Ensure this is single node cluster + grep -qi '^Nodes:.*1$' "$quorumtool_res_file" + # Current node id is 1 + grep -qi '^Node ID:.*1$' "$quorumtool_res_file" + # Is quorate (libquorum) + if [ "$1" == "yes" ];then + grep -qi '^Quorate:.*Yes$' "$quorumtool_res_file" + else + grep -qi '^Quorate:.*No$' "$quorumtool_res_file" + fi + + # Quorum is 2 + grep -qi '^Quorum:.*2' "$quorumtool_res_file" + + # Is quorate (libvotequorum) + if [ "$1" == "yes" ];then + grep -qi '^Flags:.*Quorate' "$quorumtool_res_file" + fi + + rm -f "$quorumtool_res_file" +} + +# Test corosync-qdevice-tool by waiting for connected state and +# checking heuristics results +test_qdevice_tool() { + qdevice_tool_res_file=`mktemp` + + cont=true + repeats=0 + + while $cont;do + corosync-qdevice-tool -s | tee "$qdevice_tool_res_file" + + if grep -qi '^State:.*Connected' "$qdevice_tool_res_file";then + cont=false + else + repeats=$((repeats+1)) + [ "$repeats" -le "$MAX_REPEATS" ] + + sleep 1 + fi + done + + corosync-qdevice-tool -sv | tee "$qdevice_tool_res_file" + grep -qi '^Heuristics result:.*Pass ' "$qdevice_tool_res_file" + + rm -f "$qdevice_tool_res_file" +} + +# Test qnetd tool -s (check connected clients/clusters) and -l +# (check node id, membership and heuristics) +test_qnetd_tool() { + qnetd_tool_res_file=`mktemp` + + corosync-qnetd-tool -s | tee "$qnetd_tool_res_file" + + grep -qi '^Connected clients:.*1$' "$qnetd_tool_res_file" + grep -qi '^Connected clusters:.*1$' "$qnetd_tool_res_file" + + corosync-qnetd-tool -sv | tee "$qnetd_tool_res_file" + + corosync-qnetd-tool -l | tee "$qnetd_tool_res_file" + + grep -qi "^Cluster \"$COROSYNC_CLUSTER_NAME\":\$" "$qnetd_tool_res_file" + grep -qi 'Node ID 1:$' "$qnetd_tool_res_file" + grep -qi 'Membership node list:.*1$' "$qnetd_tool_res_file" + grep -qi 'Heuristics:.*Pass$' "$qnetd_tool_res_file" + + corosync-qnetd-tool -lv | tee "$qnetd_tool_res_file" + + rm -f "$qnetd_tool_res_file" "$qnetd_tool_res_file" +} + +test_qdevice_qnetd_man_pages() { + # At least these man pages should be installed + expected_mp="corosync-qnetd corosync-qnetd-certutil corosync-qnetd-tool + corosync-qdevice corosync-qdevice-net-certutil corosync-qdevice-tool" + + for mp in $expected_mp;do + man -w "$mp" + done +} + +######## +# main # +######## +if [ -z "$PREFIX" ];then + echo "PREFIX not defined. Do not run *.inc.sh directly" + exit 1 +fi + +test_corosync_qdevice_h +test_corosync_qnetd_h + +test_qdevice_qnetd_man_pages + +test_crt_creation + +test_qnetd_start +test_corosync_start + +test_corosync_quorumtool "no" + +test_qdevice_start + +test_qdevice_tool +test_qnetd_tool +test_corosync_quorumtool "yes" + +test_qdevice_stop +test_corosync_stop +test_qnetd_stop