diff --git a/clufter-0.77.2-tests.tar.xz b/clufter-0.77.2-tests.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..92c90903b744c6d92e77dab58f30385a151cc2d4 Binary files /dev/null and b/clufter-0.77.2-tests.tar.xz differ diff --git a/clufter-0.77.2.tar.gz b/clufter-0.77.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..7e5eaeba0564d172f5da3e044161633d872efb69 Binary files /dev/null and b/clufter-0.77.2.tar.gz differ diff --git a/clufter.spec b/clufter.spec new file mode 100644 index 0000000000000000000000000000000000000000..6d7ea62c2d7e6923895084e77d0827d80a907d8f --- /dev/null +++ b/clufter.spec @@ -0,0 +1,468 @@ +%{?python_enable_dependency_generator} +# virtual provides: +# clufter -> clufter-cli +# clufter-lib -> python.+-clufter (any if multiple) +# python-clufter -> python2-clufter (subject of change) + +# conditionals: +%bcond_with python2 + +# https://fedoraproject.org/wiki/Packaging:Python_Appendix#Manual_byte_compilation +%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g') + +Name: clufter +Version: 0.77.2 +Release: 1 +Summary: Tool/library for transforming/analyzing cluster configuration formats +License: GPLv2+ +URL: https://pagure.io/%{name} + +BuildRequires: gcc +# required for autosetup macro +BuildRequires: git-core +%if 0%{defined gpgverify} +# required for OpenPGP package signature verification (per guidelines) +BuildRequires: gnupg2 +%endif + +%if %{with python2} +# Python 2 related +BuildRequires: python2-devel +BuildRequires: python2-setuptools +BuildRequires: python2-lxml +%endif + +# Python 3 related +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-lxml +BuildRequires: python3-distro + +# following to ensure "which bash" (and, in extension, "which sh") works +BuildRequires: bash which + +BuildRequires: pkgconfig(libxml-2.0) + +# schemadir path pointer (former since pacemaker 2.0.3) +%if 0%{?fedora} >= 32 +BuildRequires: pkgconfig(pacemaker-schemas) +%else +BuildRequires: pkgconfig(pacemaker-cib) +%endif +# nschemas themselves (former since pacemaker 2.0.1) +%if 0%{?fedora} >= 30 +BuildRequires: pacemaker-schemas +%else +BuildRequires: pacemaker +%endif + +# needed to squash multi-file schemas to single file +BuildRequires: jing +# needed for xsltproc and xmllint respectively +BuildRequires: libxslt libxml2 + +#global test_version +%global testver %{?test_version}%{?!test_version:%{version}} + +Source0: https://releases.pagure.org/%{name}/%{name}-%{version}.tar.gz +Source1: https://releases.pagure.org/%{name}/%{name}-%{testver}-tests.tar.xz +Source2: https://pagure.io/%{name}/raw/v%{version}/f/misc/fix-jing-simplified-rng.xsl +#Source3: https://pagure.io/#{name}/raw/v#{version}/f/misc/pacemaker-borrow-schemas +Source3: https://pagure.io/%{name}/raw/50377b47601b88381537fa13ab466fe2cb37c56a/f/misc/pacemaker-borrow-schemas +%if 0%{defined gpgverify} +Source4: https://releases.pagure.org/%{name}/%{name}-%{version}.tar.gz.asc +# publicly stated signature key rollover policy: +# https://lists.clusterlabs.org/pipermail/users/2019-August/026234.html +Source5: https://releases.pagure.org/%{name}/%{name}-2019-08-15-5CD7F9EF.keyring +%endif + +#Patch0: https://pagure.io/clufter/c/b83e3091a7febd715cc0502dc154e43edb2d44f1.patch#/compat-Python-3.9-no-longer-offers-collections.Mutable-ABCs.patch +#Patch1: https://pagure.io/clufter/c/2b1b834972a8834410d9e0c348c9aeda07c010af.patch#/compat-Python-3.9-no-longer-raises-ValueError-at-some-bound.patch +#Patch2: https://pagure.io/clufter/c/7f4125ceefaf1dd1fb66bf96509c4b0acf2d5e94.patch#/plugin_registry-fix-a-problem-with-native-plugins-missing.patch +Patch0: compat-Python-3.9-no-longer-offers-collections.Mutable-ABCs.patch +Patch1: compat-Python-3.9-no-longer-raises-ValueError-at-some-bound.patch +Patch2: plugin_registry-fix-a-problem-with-native-plugins-missing.patch +%description +While primarily aimed at (CMAN,rgmanager)->(Corosync/CMAN,Pacemaker) cluster +stacks configuration conversion (as per RHEL trend), the command-filter-format +framework (capable of XSLT) offers also other uses through its plugin library. + +%package cli +Summary: Tool for transforming/analyzing cluster configuration formats +Provides: %{name} = %{version}-%{release} + +BuildRequires: bash-completion + +BuildRequires: help2man + +# following for pkg_resources module +Requires: python3-setuptools +Requires: python3-%{name} = %{version}-%{release} +Requires: %{_bindir}/nano +BuildArch: noarch + +%description cli +While primarily aimed at (CMAN,rgmanager)->(Corosync/CMAN,Pacemaker) cluster +stacks configuration conversion (as per RHEL trend), the command-filter-format +framework (capable of XSLT) offers also other uses through its plugin library. + +This package contains %{name} command-line interface for the underlying +library (packaged as python3-%{name}). + +%if %{with python2} +%package -n python2-%{name} +Summary: Library for transforming/analyzing cluster configuration formats +License: GPLv2+ and GFDL + +Provides: %{name}-lib = %{version}-%{release} +%{?python_provide:%python_provide python2-%{name}} +Requires: %{name}-bin = %{version}-%{release} +BuildArch: noarch + +%description -n python2-%{name} +While primarily aimed at (CMAN,rgmanager)->(Corosync/CMAN,Pacemaker) cluster +stacks configuration conversion (as per RHEL trend), the command-filter-format +framework (capable of XSLT) offers also other uses through its plugin library. + +This package contains %{name} library including built-in plugins. +%endif + +%package -n python3-%{name} +Summary: Library for transforming/analyzing cluster configuration formats +License: GPLv2+ and GFDL + +Provides: %{name}-lib = %{version}-%{release} +%{?python_provide:%python_provide python3-%{name}} +%if %{without python2} +Obsoletes: python-%{name} < %{version}-%{release} +Obsoletes: python2-%{name} < %{version}-%{release} +%endif +Requires: %{name}-bin = %{version}-%{release} +BuildArch: noarch + +%description -n python3-%{name} +While primarily aimed at (CMAN,rgmanager)->(Corosync/CMAN,Pacemaker) cluster +stacks configuration conversion (as per RHEL trend), the command-filter-format +framework (capable of XSLT) offers also other uses through its plugin library. + +This package contains %{name} library including built-in plugins. + +%package bin +Summary: Common internal compiled files for %{name} +License: GPLv2+ + +Requires: %{name}-common = %{version}-%{release} + +%description bin +While primarily aimed at (CMAN,rgmanager)->(Corosync/CMAN,Pacemaker) cluster +stacks configuration conversion (as per RHEL trend), the command-filter-format +framework (capable of XSLT) offers also other uses through its plugin library. + +This package contains internal, arch-specific files for %{name}. + +%package common +Summary: Common internal data files for %{name} +License: GPLv2+ +BuildArch: noarch + +%description common +While primarily aimed at (CMAN,rgmanager)->(Corosync/CMAN,Pacemaker) cluster +stacks configuration conversion (as per RHEL trend), the command-filter-format +framework (capable of XSLT) offers also other uses through its plugin library. + +This package contains internal, arch-agnostic files for %{name}. + +%package lib-general +Summary: Extra %{name} plugins usable for/as generic/auxiliary products +Requires: %{name}-lib = %{version}-%{release} +BuildArch: noarch + +%description lib-general +This package contains set of additional plugins targeting variety of generic +formats often serving as a byproducts in the intermediate steps of the overall +process arrangement: either experimental commands or internally unused, +reusable formats and filters. + +%package lib-ccs +Summary: Extra plugins for transforming/analyzing CMAN configuration +Requires: %{name}-lib-general = %{version}-%{release} +BuildArch: noarch + +%description lib-ccs +This package contains set of additional plugins targeting CMAN cluster +configuration: either experimental commands or internally unused, reusable +formats and filters. + +%package lib-pcs +Summary: Extra plugins for transforming/analyzing Pacemaker configuration +Requires: %{name}-lib-general = %{version}-%{release} +BuildArch: noarch + +%description lib-pcs +This package contains set of additional plugins targeting Pacemaker cluster +configuration: either experimental commands or internally unused, reusable +formats and filters. + +%prep +%if 0%{defined gpgverify} +%{gpgverify} --keyring='%{SOURCE5}' --signature='%{SOURCE4}' --data='%{SOURCE0}' +%endif +%setup -b1 -q +pushd clufter +%global __scm git_am +%__scm_setup_git +%autopatch -p1 +popd + +%if "%{testver}" != "%{version}" + %{__cp} -a ../"%{name}-%{testver}"/* . +%endif + +## for some esoteric reason, the line above has to be empty +%{__python3} setup.py saveopts -f setup.cfg pkg_prepare \ + --ccs-flatten='%{_libexecdir}/%{name}-%{version}/ccs_flatten' \ + --editor='%{_bindir}/nano' \ + --extplugins-shared='%{_datarootdir}/%{name}/ext-plugins' \ + --ra-metadata-dir='%{_datadir}/cluster' \ + --ra-metadata-ext='metadata' \ + --shell-posix='%(which sh 2>/dev/null || echo /bin/SHELL-POSIX)' \ + --shell-bashlike='%(which bash 2>/dev/null || echo /bin/SHELL-BASHLIKE)' +%{__python3} setup.py saveopts -f setup.cfg pkg_prepare \ + --report-bugs='https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=%{name}' + +%build +%if %{with python2} +%py2_build +%endif +# see https://fedoraproject.org/wiki/Changes/python3_c.utf-8_locale; +# specifically: +# File "setup.py", line 466, in _pkg_prepare_file +# content = fr.read() +# File "/usr/lib64/python3.5/encodings/ascii.py", line 26, in decode +# return codecs.ascii_decode(input, self.errors)[0] +# UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 221: ordinal not in range(128) +export LC_ALL=C.UTF-8 LANG=C.UTF-8 +%py3_build + +%{__python3} -I ./run-dev --skip-ext --completion-bash 2>/dev/null \ + | sed 's|run[-_]dev|%{name}|g' > .bashcomp +# generate man pages (proper commands and aliases from a sorted sequence) +%{__mkdir_p} -- .manpages/man1 +{ echo; %{__python3} -I ./run-dev -l | sed -n 's|^ \(\S\+\).*|\1|p' \ + | sort; } > .subcmds +sed -e 's:\(.\+\):\\\&\\fIrun_dev-\1\\fR\\\|(1), :' \ + -e '1s|\(.*\)|\[SEE ALSO\]\n|' \ + -e '$s|\(.*\)|\1\nand perhaps more|' \ + .subcmds > .see-also +help2man -N -h -H -i .see-also \ + -n "$(sed -n '2s|[^(]\+(\([^)]\+\))|\1|p' README)" \ + '%{__python3} -I ./run-dev' | sed 's|run\\\?[-_]dev|%{name}|g' \ + > ".manpages/man1/%{name}.1" +while read cmd; do + [ -n "${cmd}" ] || continue + echo -e "#\!/bin/sh\n{ [ \$# -ge 1 ] && [ \"\$1\" = \"--version\" ] \ + && %{__python3} -I ./run-dev \"\$@\" \ + || %{__python3} -I ./run-dev \"${cmd}\" \"\$@\"; }" > ".tmp-${cmd}" + chmod +x ".tmp-${cmd}" + grep -v "^${cmd}\$" .subcmds \ + | grep -e '^$' -e "$(echo ${cmd} | cut -d- -f1)\(-\|\$\)" \ + | sed -e 's:\(.\+\):\\\&\\fIrun_dev-\1\\fR\\\|(1), :' \ + -e '1s|\(.*\)|\[SEE ALSO\]\n\\\&\\fIrun_dev\\fR\\\|(1), \n|' \ + -e '$s|\(.*\)|\1\nand perhaps more|' > .see-also + # XXX uses ";;&" bashism + case "${cmd}" in + ccs[2-]*) + sed -i \ + '1s:\(.*\):\1\n\\\&\\fIcluster.conf\\fR\\\|(5), \\\&\\fIccs\\fR\\\|(7), :' \ + .see-also + ;;& + ccs2pcs*) + sed -i \ + '1s:\(.*\):\1\n\\\&\\fI%{_defaultdocdir}/%{name}-%{version}/rgmanager-pacemaker\\fR\\\|, :' \ + .see-also + ;;& + *[2-]pcscmd*) + sed -i '1s:\(.*\):\1\n\\\&\\fIpcs\\fR\\\|(8), :' .see-also + ;;& + esac + help2man -N -h -H -i .see-also -n "${cmd}" "./.tmp-${cmd}" \ + | sed 's|run\\\?[-_]dev|%{name}|g' \ + > ".manpages/man1/%{name}-${cmd}.1" +done < .subcmds + +OUTPUTDIR=.schemas POSTPROCESS="%{SOURCE2}" sh "%{SOURCE3}" --clobber + +%install +%if %{with python2} +%py2_install +%endif +# see build section +export LC_ALL=C.UTF-8 LANG=C.UTF-8 +%py3_install + +# following is needed due to umask 022 not taking effect(?) leading to 775 +%{__chmod} -- g-w '%{buildroot}%{_libexecdir}/%{name}-%{version}/ccs_flatten' +# %%{_bindir}/%%{name} should have been created +test -f '%{buildroot}%{_bindir}/%{name}' \ + || %{__install} -D -pm 644 -- '%{buildroot}%{_bindir}/%{name}' \ + '%{buildroot}%{_bindir}/%{name}' + +# move data files from python-specific locations to a single common one +# and possibly symlink that back +%{__mkdir_p} -- '%{buildroot}%{_datarootdir}/%{name}/formats' +for format in cib corosync; do + %{__cp} -a -t '%{buildroot}%{_datarootdir}/%{name}/formats' \ + -- "%{buildroot}%{python3_sitelib}/%{name}/formats/${format}" +%if %{with python2} + %{__rm} -f -- "%{buildroot}%{python2_sitelib}/%{name}/formats/${format}"/* + ln -s -t "%{buildroot}%{python2_sitelib}/%{name}/formats/${format}" \ + -- $(pushd "%{buildroot}%{_datarootdir}/%{name}/formats/${format}" >/dev/null; \ + ls -1A | sed "s:.*:%{_datarootdir}/%{name}/formats/${format}/\\0:") +%endif + %{__rm} -f -- "%{buildroot}%{python3_sitelib}/%{name}/formats/${format}"/* + ln -s -t "%{buildroot}%{python3_sitelib}/%{name}/formats/${format}" \ + -- $(pushd "%{buildroot}%{_datarootdir}/%{name}/formats/${format}" >/dev/null; \ + ls -1A | sed "s:.*:%{_datarootdir}/%{name}/formats/${format}/\\0:") +done + +# move ext-plugins from python-specific locations to a single common one +# incl. the different sorts of precompiled bytecodes +%{__mkdir_p} -- '%{buildroot}%{_datarootdir}/%{name}/ext-plugins' +%if %{with python2} +mv -t '%{buildroot}%{_datarootdir}/%{name}/ext-plugins' \ + -- '%{buildroot}%{python2_sitelib}/%{name}'/ext-plugins/*/ +%endif +%{__cp} -af -t '%{buildroot}%{_datarootdir}/%{name}/ext-plugins' \ + -- '%{buildroot}%{python3_sitelib}/%{name}'/ext-plugins/* +%{__rm} -rf -- '%{buildroot}%{python3_sitelib}/%{name}'/ext-plugins/*/ + +# byte-compilation +# py_byte_compile macro introduced in Fedora in python3 for f13, f30 is +# then boundary where no to use sanity options (against revamped version +# of that macro, since it exactly abuses what shall not be done in the +# buildroot, alas...) +%if %{with python2} +%if ("%{?quote:1}" != "" && "%{?quote:1}" != "1" && (0%{?fedora} && 0%{?fedora} <= 30 || 0%{?rhel} && 0%{?rhel} <= 8)) +%py_byte_compile %{quote:%{__python2} -Es} %{python2_sitelib}/%{name} +%py_byte_compile %{quote:%{__python2} -Es} %{buildroot}%{_datarootdir}/%{name}/ext-plugins +%else +%py_byte_compile %{__python2} %{python2_sitelib}/%{name} +%py_byte_compile %{__python2} %{buildroot}%{_datarootdir}/%{name}/ext-plugins +%endif +%endif +%if ("%{?quote:1}" != "" && "%{?quote:1}" != "1" && (0%{?fedora} && 0%{?fedora} <= 30 || 0%{?rhel} && 0%{?rhel} <= 8)) +%py_byte_compile %{quote:%{__python3} -I} %{python3_sitelib}/%{name} +%py_byte_compile %{quote:%{__python3} -I} %{buildroot}%{_datarootdir}/%{name}/ext-plugins +%else +%py_byte_compile %{__python3} %{python3_sitelib}/%{name} +%py_byte_compile %{__python3} %{buildroot}%{_datarootdir}/%{name}/ext-plugins +%endif + +declare bashcompdir="$(pkg-config --variable=completionsdir bash-completion \ + || echo '%{_datadir}/bash-completion/completions')" +declare bashcomp="${bashcompdir}/%{name}" +%{__install} -D -pm 644 -- \ + .bashcomp '%{buildroot}%{_sysconfdir}/%{name}/bash-completion' +%{__mkdir_p} -- "%{buildroot}${bashcompdir}" +ln -s '%{_sysconfdir}/%{name}/bash-completion' "%{buildroot}${bashcomp}" +# own %%{_datadir}/bash-completion in case of ...bash-completion/completions, +# more generally any path up to any of /, /usr, /usr/share, /etc +while true; do + test "$(dirname "${bashcompdir}")" != "/" \ + && test "$(dirname "${bashcompdir}")" != "%{_prefix}" \ + && test "$(dirname "${bashcompdir}")" != "%{_datadir}" \ + && test "$(dirname "${bashcompdir}")" != "%{_sysconfdir}" \ + || break + bashcompdir="$(dirname "${bashcompdir}")" +done +cat >.bashcomp-files <<-EOF + ${bashcompdir} + %dir %{_sysconfdir}/%{name} + %verify(not size md5 mtime) %{_sysconfdir}/%{name}/bash-completion +EOF +%{__mkdir_p} -- '%{buildroot}%{_mandir}' +%{__cp} -a -t '%{buildroot}%{_mandir}' -- .manpages/* +%{__cp} -a -f -t '%{buildroot}%{_datarootdir}/%{name}/formats/cib' \ + -- .schemas/pacemaker-*.*.rng +%{__mkdir_p} -- '%{buildroot}%{_defaultdocdir}/%{name}-%{version}' +%{__cp} -a -t '%{buildroot}%{_defaultdocdir}/%{name}-%{version}' \ + -- gpl-2.0.txt doc/*.txt doc/rgmanager-pacemaker + +%check +# just a basic sanity check +# we need to massage RA metadata files and PATH so the local run works +# XXX we could also inject buildroot's site_packages dir to PYTHONPATH +declare ret=0 \ + ccs_flatten_dir="$(dirname '%{buildroot}%{_libexecdir}/%{name}-%{version}/ccs_flatten')" +ln -s '%{buildroot}%{_datadir}/cluster'/*.'metadata' \ + "${ccs_flatten_dir}" +%if %{with python2} +PATH="${PATH:+${PATH}:}${ccs_flatten_dir}" PYTHONEXEC="%{__python2} -Es" ./run-tests +%endif +# see build section +export LC_ALL=C.UTF-8 LANG=C.UTF-8 +PATH="${PATH:+${PATH}:}${ccs_flatten_dir}" PYTHONEXEC="%{__python3} -I" ./run-tests +ret=$? +%{__rm} -f -- "${ccs_flatten_dir}"/*.'metadata' +[ ${ret} -eq 0 ] || exit ${ret} + +%post cli +if [ $1 -gt 1 ]; then # no gain regenerating it w/ fresh install (same result) +declare bashcomp="%{_sysconfdir}/%{name}/bash-completion" +%{_bindir}/%{name} --completion-bash > "${bashcomp}" 2>/dev/null || : +fi + +%post lib-general +declare bashcomp="%{_sysconfdir}/%{name}/bash-completion" +# if the completion file is not present, suppose it is not desired +test -x '%{_bindir}/%{name}' && test -f "${bashcomp}" \ + && %{_bindir}/%{name} --completion-bash > "${bashcomp}" 2>/dev/null || : + +%post lib-ccs +declare bashcomp="%{_sysconfdir}/%{name}/bash-completion" +# if the completion file is not present, suppose it is not desired +test -x '%{_bindir}/%{name}' && test -f "${bashcomp}" \ + && %{_bindir}/%{name} --completion-bash > "${bashcomp}" 2>/dev/null || : + +%post lib-pcs +declare bashcomp="%{_sysconfdir}/%{name}/bash-completion" +# if the completion file is not present, suppose it is not desired +test -x '%{_bindir}/%{name}' && test -f "${bashcomp}" \ + && %{_bindir}/%{name} --completion-bash > "${bashcomp}" 2>/dev/null || : + +%files cli -f .bashcomp-files +%{_mandir}/man1/*.1* +%{_bindir}/%{name} + +%if %{with python2} +%files -n python2-%{name} +%{python2_sitelib}/%{name} +%{python2_sitelib}/%{name}-*.egg-info +%endif + +%files -n python3-%{name} +%{python3_sitelib}/%{name} +%{python3_sitelib}/%{name}-*.egg-info + +%files bin +%{_libexecdir}/%{name}-%{version} + +%files common +%{_datadir}/cluster +%{_datarootdir}/%{name} +%dir %{_defaultdocdir}/%{name}-%{version} +%{_defaultdocdir}/%{name}-%{version}/*[^[:digit:]] +%license %{_defaultdocdir}/%{name}-%{version}/*[[:digit:]].txt + +%files lib-general +%{_datarootdir}/%{name}/ext-plugins/lib-general + +%files lib-ccs +%{_datarootdir}/%{name}/ext-plugins/lib-ccs + +%files lib-pcs +%{_datarootdir}/%{name}/ext-plugins/lib-pcs + +%changelog +* Fri Dec 4 2020 liqiuyu - 0.77.2-1 +- Init python-clufter project \ No newline at end of file diff --git a/compat-Python-3.9-no-longer-offers-collections.Mutable-ABCs.patch b/compat-Python-3.9-no-longer-offers-collections.Mutable-ABCs.patch new file mode 100644 index 0000000000000000000000000000000000000000..070d81df862568015f5090dcaea8ff6d2f878c8a --- /dev/null +++ b/compat-Python-3.9-no-longer-offers-collections.Mutable-ABCs.patch @@ -0,0 +1,129 @@ +From b83e3091a7febd715cc0502dc154e43edb2d44f1 Mon Sep 17 00:00:00 2001 +From: Jan Pokorný +Date: Jan 17 2020 14:20:25 +0000 +Subject: compat: Python 3.9 no longer offers collections.Mutable* ABCs + + +Solution is to move over onto collections.abc dedicated submodule +that hosts these exclusively since 3.9. + +References: +https://docs.python.org/3/whatsnew/3.3.html#collections +https://docs.python.org/3/whatsnew/3.7.html#id3 +https://docs.python.org/3.7/library/collections.html#collections-container-datatypes +https://docs.python.org/3.9/whatsnew/3.9.html#removed + +Signed-off-by: Jan Pokorný + +--- + +diff --git a/command.py b/command.py +index 1330bef..92cdf22 100644 +--- a/command.py ++++ b/command.py +@@ -1,11 +1,14 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2017 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + """Base command stuff (TBD)""" + __author__ = "Jan Pokorný " + +-from collections import MutableMapping ++try: ++ from collections.abc import MutableMapping ++except ImportError: ++ from collections import MutableMapping + try: + from itertools import zip_longest + except ImportError: # PY2 backward compatibility +diff --git a/command_context.py b/command_context.py +index c7331ea..b6135df 100644 +--- a/command_context.py ++++ b/command_context.py +@@ -1,11 +1,14 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2017 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + """Command context, i.e., state distributed along filters chain""" + __author__ = "Jan Pokorný " + +-from collections import MutableMapping ++try: ++ from collections.abc import MutableMapping ++except ImportError: ++ from collections import MutableMapping + from logging import getLogger + + from .error import ClufterError +diff --git a/filters/cmd_wrap.py b/filters/cmd_wrap.py +index 89c9829..0166b68 100644 +--- a/filters/cmd_wrap.py ++++ b/filters/cmd_wrap.py +@@ -1,5 +1,5 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2017 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + """cmd-wrap filter""" +@@ -12,7 +12,11 @@ from ..utils_2to3 import bytes_enc, str_enc, xrange + from ..utils_func import add_item + from ..utils_prog import FancyOutput + +-from collections import MutableMapping, defaultdict ++try: ++ from collections.abc import MutableMapping ++except ImportError: ++ from collections import MutableMapping ++from collections import defaultdict + from logging import getLogger + from os import getenv, isatty + from sys import maxsize +diff --git a/protocol.py b/protocol.py +index e41fc57..3334324 100644 +--- a/protocol.py ++++ b/protocol.py +@@ -1,11 +1,14 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2017 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + """Base protocol stuff (metaclass, etc.)""" + __author__ = "Jan Pokorný " + +-from collections import MutableMapping ++try: ++ from collections.abc import MutableMapping ++except ImportError: ++ from collections import MutableMapping + from logging import getLogger + + from .plugin_registry import PluginRegistry +diff --git a/utils_prog.py b/utils_prog.py +index c427791..e39a141 100644 +--- a/utils_prog.py ++++ b/utils_prog.py +@@ -1,12 +1,15 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2017 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + """Program-specific commons""" + __author__ = "Jan Pokorný " + + import logging +-from collections import Mapping, MutableMapping, MutableSequence, MutableSet ++try: ++ from collections.abc import Mapping, MutableMapping, MutableSequence, MutableSet ++except ImportError: ++ from collections import Mapping, MutableMapping, MutableSequence, MutableSet + from functools import reduce + from optparse import Option + from os import environ, fdopen, isatty, pathsep + diff --git a/compat-Python-3.9-no-longer-raises-ValueError-at-some-bound.patch b/compat-Python-3.9-no-longer-raises-ValueError-at-some-bound.patch new file mode 100644 index 0000000000000000000000000000000000000000..f8d1a81b6f6d6e6eb3d8b7eb035d09d5a6d9b1a6 --- /dev/null +++ b/compat-Python-3.9-no-longer-raises-ValueError-at-some-bound.patch @@ -0,0 +1,119 @@ +From 2b1b834972a8834410d9e0c348c9aeda07c010af Mon Sep 17 00:00:00 2001 +From: Jan Pokorný +Date: Jan 18 2020 00:06:11 +0000 +Subject: compat: Python 3.9 no longer raises ValueError at some boundary imports + + +References: +https://docs.python.org/3.9/whatsnew/3.9.html#changes-in-the-python-api + +Signed-off-by: Jan Pokorný + +--- + +diff --git a/filters/cluster/__init__.py b/filters/cluster/__init__.py +index ee33a32..e3cac49 100644 +--- a/filters/cluster/__init__.py ++++ b/filters/cluster/__init__.py +@@ -1,5 +1,5 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2017 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + __author__ = "Jan Pokorný " +@@ -8,7 +8,7 @@ __author__ = "Jan Pokorný " + try: + from ....utils_2to3 import bytes_enc, str_enc + from ....utils_xslt import xslt_is_member +-except ValueError: # Value? ++except (ImportError, ValueError): + from ...utils_2to3 import bytes_enc, str_enc + from ...utils_xslt import xslt_is_member + +@@ -234,7 +234,7 @@ from time import time + try: + from ....utils import lazystring + from ....utils_prog import getenv_namespaced +-except ValueError: # Value? ++except (ImportError, ValueError): + from ...utils import lazystring + from ...utils_prog import getenv_namespaced + +@@ -323,7 +323,7 @@ ccs2needlexml = lazystring(lambda: ('''\ + try: + from .... import package_name, version + from ....utils_xslt import xslt_id_friendly +-except ValueError: ++except (ImportError, ValueError): + from ... import package_name, version + from ...utils_xslt import xslt_id_friendly + ccsflat2cibprelude_self_id = ' '.join((package_name(), version)) +@@ -492,7 +492,7 @@ ccsflat2cibprelude = ('''\ + # following 2nd chance import is to allow direct usage context (testing, etc.) + try: + from ....utils_xslt import xslt_is_member +-except ValueError: # Value? ++except (ImportError, ValueError): + from ...utils_xslt import xslt_is_member + + ccs_revitalize_fa_domain = tuple( +@@ -673,7 +673,7 @@ ccs_obfuscate_identifiers = '''\ + # following 2nd chance import is to allow direct usage context (testing, etc.) + try: + from ....filters._2pcscmd import coro2pcscmd +-except ValueError: # Value? ++except (ImportError, ValueError): + from ...filters._2pcscmd import coro2pcscmd + + ccspcmk2pcscmd = coro2pcscmd(cman='', node='clusternode', totem='') +diff --git a/filters/cluster/rm/_fs.py b/filters/cluster/rm/_fs.py +index 8e588fa..9387845 100644 +--- a/filters/cluster/rm/_fs.py ++++ b/filters/cluster/rm/_fs.py +@@ -1,5 +1,5 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2017 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + __author__ = "Jan Pokorný " +@@ -7,7 +7,7 @@ __author__ = "Jan Pokorný " + # following 2nd chance import is to allow direct usage context (testing, etc.) + try: + from ....utils_xslt import xslt_is_member +-except ValueError: # Value? ++except (ImportError, ValueError): + from ...utils_xslt import xslt_is_member + + ### +@@ -18,7 +18,7 @@ except ValueError: # Value? + + try: + from ....utils_cib import ResourceSpec +-except ValueError: ++except (ImportError, ValueError): + from ...utils_cib import ResourceSpec + + ccsflat2cibprelude = (''' +diff --git a/filters/corosync/__init__.py b/filters/corosync/__init__.py +index cff1a2a..611955d 100644 +--- a/filters/corosync/__init__.py ++++ b/filters/corosync/__init__.py +@@ -1,5 +1,5 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2015 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + __author__ = "Jan Pokorný " +@@ -9,7 +9,7 @@ __author__ = "Jan Pokorný " + # following 2nd chance import is to allow direct usage context (testing, etc.) + try: + from ....filters._2pcscmd import coro2pcscmd +-except ValueError: # Value? ++except (ImportError, ValueError): + from ...filters._2pcscmd import coro2pcscmd + + needlexml2pcscmd = coro2pcscmd(node='', quorum='', totem='') + diff --git a/fix-jing-simplified-rng.xsl b/fix-jing-simplified-rng.xsl new file mode 100644 index 0000000000000000000000000000000000000000..580d192008c1425d33cb0f0effc1eded0add60d7 --- /dev/null +++ b/fix-jing-simplified-rng.xsl @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pacemaker-borrow-schemas b/pacemaker-borrow-schemas new file mode 100644 index 0000000000000000000000000000000000000000..888272d909986b1bb8b674e4c0060dff925f8355 --- /dev/null +++ b/pacemaker-borrow-schemas @@ -0,0 +1,72 @@ +#!/bin/sh +# Copyright 2020 Red Hat, Inc. +# Part of clufter project +# Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + +# A helper for "borrow validation schemas from pacemaker" process. + +die() { echo; echo "$@"; exit 1; } + +# $1 ... input directory with original pacemaker schemas +# $2 ... output directory with consolidated schemas +# $3 ... schemas to skip (as posix-egrep expression) +# $4 ... postprocess XSLT +# $5 ... clobber existing files? (true if set and non-null) +consolidate() { + inputdir="${1}"; outputdir="${2}"; skipschemas="${3}"; postprocess="${4}" + test "${#}" -lt 5 || clobber="${5}" + mkdir -p -- "${outputdir}" + # for all the schema versions at the boundary of the "major" bump, + # except for the lower boundary of the first one (i.e. pacemaker-1.0) + # -- the versions in between are not interesting from validation POV + for base in $( + find "${inputdir}" -regextype posix-egrep -regex "${skipschemas}" -prune \ + -o -name 'pacemaker-*.rng' -printf '%P\n' | sort -V \ + | sed -e 'N;/^\(pacemaker-[0-9]\)\.\([0-9][0-9]*\)\.rng\n\1\.\([0-9][0-9]*\)\.rng$/!p;D'); do + f="${inputdir}/${base}" + printf "processing: ${f} ... " + test -f "${f}" || continue + sentinel=10; old=/dev/null; new="${f}" + # until the jing output converged (simplification gets idempotent) + # as prescribed by did-size-change heuristic (or sentinel is hit) + while [ "$(stat -c '%s' "${old}")" != "$(stat -c '%s' "${new}")" ]; do + [ "$((sentinel -= 1))" -gt 0 ] || break + [ "${old}" = "${f}" ] && old="${outputdir}/${base}"; + [ "${new}" = "${f}" ] \ + && { old="${f}"; new="${outputdir}/${base}.new"; } \ + || cp -f "${new}" "${old}" + jing -is "${old}" > "${new}" + #printf "(%d -> %d) " "$(stat -c '%s' "${old}")" "$(stat -c '%s' "${new}")" + done + printf "%d iterations" "$((10 - ${sentinel}))" + test -z "${clobber-}" && test -s "${old}" && die "file ${old} already exists" || : + if [ -z "${postprocess}" ]; then + mv "${new}" "${old}" + printf ", moved\n" + else + # xmllint drops empty lines caused by the applied transformation + xsltproc --stringparam filename-or-version "${base}" \ + "${postprocess}" "${new}" \ + | xmllint --format - > "${old}" + rm -f -- "${new}" + printf ", postprocessed\n" + fi + done +} + +which jing >/dev/null 2>&1 || die "jing (from jing-trang project) required" + +: "${INPUTDIR=$(pkg-config --variable schemadir pacemaker-schemas 2>/dev/null \ + || pkg-config --variable schemadir pacemaker-cib)}" +test -n "${INPUTDIR}" || die "Input dir with pacemaker schemas not known" + +: "${OUTPUTDIR=schemas-consolidated}" +test -n "${OUTPUTDIR}" || die "Output dir for consolidated schemas not known" + +: "${POSTPROCESS=$(dirname "${0}")/fix-jing-simplified-rng.xsl}" + +# skip non-defaults of upstream releases +#: "${SKIPSCHEMAS=.*/pacemaker-(1\.0|2\.[126]).rng}" +: "${SKIPSCHEMAS=".*/pacemaker-next\.rng"}" # only skip WIP schema by default + +consolidate "${INPUTDIR}" "${OUTPUTDIR}" "${SKIPSCHEMAS}" "${POSTPROCESS}" "${@}" diff --git a/plugin_registry-fix-a-problem-with-native-plugins-missing.patch b/plugin_registry-fix-a-problem-with-native-plugins-missing.patch new file mode 100644 index 0000000000000000000000000000000000000000..fe307ad026e55e17fc93a71d6a342b64cf3a61bf --- /dev/null +++ b/plugin_registry-fix-a-problem-with-native-plugins-missing.patch @@ -0,0 +1,69 @@ +From 7f4125ceefaf1dd1fb66bf96509c4b0acf2d5e94 Mon Sep 17 00:00:00 2001 +From: Jan Pokorný +Date: Jan 18 2020 00:29:38 +0000 +Subject: plugin_registry: fix a problem with "native plugins" missing in lookup + + +For some reason, this does only appear to be a problem under Python 3 +(cannot find a trace[*] of this problem under older Python 2 build logs) +and it is caused with these "native plugins" missing from "wildcard" +(non-specific) "init_lookup" invocation of the plugin registry at hand. + +[*] e.g. +> test01 (ccs2coroxml.Main) ... WARNING:clufter.filter:Resolve at `ccs-artefacts' filter: `SimpleFormat' (#1) format fail +> WARNING:clufter.filter:Resolve at `cmd-annotate' filter: `Nothing' (#0) format fail +> WARNING:clufter.filter:Resolve at `xml2simpleconfig' filter: `XML' (#0) format fail + +Signed-off-by: Jan Pokorný + +--- + +diff --git a/plugin_registry.py b/plugin_registry.py +index 5851127..4c60acd 100644 +--- a/plugin_registry.py ++++ b/plugin_registry.py +@@ -1,5 +1,5 @@ + # -*- coding: UTF-8 -*- +-# Copyright 2019 Red Hat, Inc. ++# Copyright 2020 Red Hat, Inc. + # Part of clufter project + # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) + """Easy (at least for usage) plugin framework""" +@@ -104,7 +104,7 @@ class PluginRegistry(type): + assert '-' not in name, "name cannot contain a dash" + dname = cli_decor(name) + attrs = attrs or {} +- # seems more reasonable than plying even higher meta magic game ++ # seems more reasonable than playing even higher meta magic game + assert not(attrs) or '__classcell__' not in attrs, \ + ("{0} plugin: refrain from '__class__'/'super' (Py3.8+ limit)" + ).format(name) +@@ -287,9 +287,10 @@ class PluginManager(object): + + @classmethod + def lookup(cls, plugins, registry=None, **kwargs): +- ret, to_discover = {}, set() ++ ret, to_discover, wildcard = {}, set(), True + registry = cls._default_registry if registry is None else registry + for plugin in args2sgpl(plugins): ++ wildcard = False + # XXX we could introspect sys.modules here as well + try: + ret[plugin] = registry.plugins[plugin] +@@ -300,9 +301,12 @@ class PluginManager(object): + + to_discover.difference_update(ret) + native_plugins = registry.native_plugins +- ret.update(filterdict_remove(to_discover, +- _fn_=lambda x: native_plugins[x], +- *native_plugins.keys())) ++ if wildcard: ++ ret.update(native_plugins) ++ else: ++ ret.update(filterdict_remove(to_discover, ++ _fn_=lambda x: native_plugins[x], ++ *native_plugins.keys())) + to_discover = apply_intercalate(tuple(to_discover)) + if to_discover: + log.debug("Couldn't look up everything: {0}".format(', '.join( + diff --git a/python-clufter.yam b/python-clufter.yam new file mode 100644 index 0000000000000000000000000000000000000000..330596a099871d9ba122c9519e8ac522b24d671f --- /dev/null +++ b/python-clufter.yam @@ -0,0 +1,4 @@ + version_control:github + src_repo:jnpkrn/clufter + tag_prefix:"^v" + separator:"." \ No newline at end of file