From 48490e1ce586abd13c92ae8c213318e5b020badb Mon Sep 17 00:00:00 2001 From: Miroslav Lisik Date: Fri, 11 Jun 2021 17:06:50 +0200 Subject: [PATCH] Resolves: rhbz#1881064 - Rebased to latest upstream sources (see CHANGELOG.md) - Removed clufter related commands --- .gitignore | 6 +- bz1881064-01-remove-clufter-commands.patch | 766 ++++++++++++++++++ ...-replace-pyOpenSSL-with-python-crypt.patch | 702 ---------------- ...t-cluster-setup-with-udp-u-transport.patch | 24 +- fix-wrong-name-for-library-command.patch | 151 ++++ pcs.spec | 275 +++---- sources | 9 +- tests/tests.yml | 16 +- 8 files changed, 1057 insertions(+), 892 deletions(-) create mode 100644 bz1881064-01-remove-clufter-commands.patch delete mode 100644 bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch create mode 100644 fix-wrong-name-for-library-command.patch diff --git a/.gitignore b/.gitignore index a89d9e7..f013d6d 100644 --- a/.gitignore +++ b/.gitignore @@ -132,6 +132,8 @@ /pcs-web-ui-0.1.5.tar.gz /pcs-web-ui-node-modules-0.1.5.tar.xz /pcs-0.10.8.tar.gz -/rexml-3.2.4.gem +/rexml-3.2.5.gem /webrick-1.7.0.gem -/pcs-web-ui-node-modules-0.1.5.fix.1.tar.xz +/pcs-web-ui-node-modules-0.1.6.tar.xz +/pcs-web-ui-0.1.6.tar.gz +/pcs-0.10.8.181-47e9.tar.gz diff --git a/bz1881064-01-remove-clufter-commands.patch b/bz1881064-01-remove-clufter-commands.patch new file mode 100644 index 0000000..8b6dccc --- /dev/null +++ b/bz1881064-01-remove-clufter-commands.patch @@ -0,0 +1,766 @@ +From 4aa1ca8221e660b21d8afcc6c5acebf48d51d628 Mon Sep 17 00:00:00 2001 +From: Tomas Jelinek +Date: Mon, 14 Jun 2021 11:39:14 +0200 +Subject: [PATCH 2/3] remove clufter commands + +--- + .gitlab-ci.yml | 1 - + CHANGELOG.md | 13 + + Makefile.am | 4 +- + README.md | 2 - + configure.ac | 5 - + mypy.ini | 6 - + pcs/cli/common/parse_args.py | 4 - + pcs/cli/routing/config.py | 14 - + pcs/config.py | 377 ------------------- + pcs/pcs.8.in | 2 - + pcs/settings.py.in | 3 - + pcs_test/Makefile.am | 1 - + pcs_test/resources/cluster.conf | 27 -- + pcs_test/tier0/cli/common/test_parse_args.py | 2 - + pcsd/Makefile.am | 1 - + pcsd/test/cluster.conf | 27 -- + rpm/pcs.spec.in | 15 - + 17 files changed, 14 insertions(+), 490 deletions(-) + delete mode 100644 pcs_test/resources/cluster.conf + delete mode 100644 pcsd/test/cluster.conf + +diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml +index 8a36b509..6602ea46 100644 +--- a/.gitlab-ci.yml ++++ b/.gitlab-ci.yml +@@ -5,7 +5,6 @@ variables: + python3-cryptography + python3-dateutil + python3-devel +- python3-distro + python3-lxml + python3-pip + python3-pycurl +diff --git a/CHANGELOG.md b/CHANGELOG.md +index 9a7f4315..75d148a4 100644 +--- a/CHANGELOG.md ++++ b/CHANGELOG.md +@@ -1,5 +1,17 @@ + # Change Log + ++## [0.11.0] ++ ++### Changed ++- Pcs no longer depends on python3-distro package ++ ++### Removed ++- Deprecated obsolete commands `pcs config import-cman` and `pcs config export ++ pcs-commands|pcs-commands-verbose` have been removed ([rhbz#1881064]) ++ ++[rhbz#1881064]: https://bugzilla.redhat.com/show_bug.cgi?id=1881064 ++ ++ + ## [Unreleased] + + ### Added +@@ -29,6 +41,7 @@ + [rhbz#1927404]: https://bugzilla.redhat.com/show_bug.cgi?id=1927404 + [rhbz#1930886]: https://bugzilla.redhat.com/show_bug.cgi?id=1930886 + ++ + ## [0.10.8] - 2021-02-01 + + ### Added +diff --git a/Makefile.am b/Makefile.am +index 6a7cc553..cba77d8d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -369,12 +369,10 @@ $(SPEC): $(SPEC).in .version config.status stamps/download_python_deps stamps/do + pylist="`ls rpm/*.tar.gz | grep -v ^rpm/pyagentx- | grep -v ^rpm/pcs- | sed -e 's#rpm/##g' -e 's#.tar.gz##'`" && \ + pysrc="`base=42; for i in $$pylist; do echo 'Source'$$base': '$$i'.tar.gz' && let "base=base+1"; done`" && \ + $(AWK) -i inplace -v r="$$pysrc" '{gsub(/@pysrc@/,r)}1' $@-t; \ +- pybundle="`for i in $$pylist; do echo $$i | grep -v ^distro- | grep -v ^dataclasses- | sed 's/\(.*\)-\(.*\)/Provides: bundled(\1) = \2/'; done`" && \ ++ pybundle="`for i in $$pylist; do echo $$i | grep -v ^dataclasses- | sed 's/\(.*\)-\(.*\)/Provides: bundled(\1) = \2/'; done`" && \ + $(AWK) -i inplace -v r="$$pybundle" '{gsub(/@pybundle@/,r)}1' $@-t; \ + pydataclassesbundle="`for i in $$pylist; do echo $$i | grep ^dataclasses- | sed 's/\(.*\)-\(.*\)/Provides: bundled(\1) = \2/'; done`" && \ + $(AWK) -i inplace -v r="$$pydataclassesbundle" '{gsub(/@pydataclassesbundle@/,r)}1' $@-t; \ +- pydistrobundle="`for i in $$pylist; do echo $$i | grep ^distro- | sed 's/\(.*\)-\(.*\)/Provides: bundled(\1) = \2/'; done`" && \ +- $(AWK) -i inplace -v r="$$pydistrobundle" '{gsub(/@pydistrobundle@/,r)}1' $@-t; \ + pycache="`echo $(MKDIR_P) $(PCS_BUNDLED_DIR_LOCAL)/src; base=41; for i in $$pylist pyagentx; do echo 'cp -f %SOURCE'$$base' rpm/' && let "base=base+1"; done`" && \ + $(AWK) -i inplace -v r="$$pycache" '{gsub(/@pycache@/,r)}1' $@-t; \ + gemlist="`for i in $$($(FIND) rpm/ -type f -name '*.gem'); do echo $$i | sed -e 's#rpm/##g' -e 's#.gem##g'; done`" && \ +diff --git a/README.md b/README.md +index efca6deb..85ab1099 100644 +--- a/README.md ++++ b/README.md +@@ -26,7 +26,6 @@ These are the runtime dependencies of pcs and pcsd: + * python 3.6+ + * python3-cryptography + * python3-dateutil 2.7.0+ +-* python3-distro (for python 3.8+) + * python3-lxml + * python3-pycurl + * python3-setuptools +@@ -41,7 +40,6 @@ These are the runtime dependencies of pcs and pcsd: + * pacemaker 2.x + + It is also recommended to have these: +-* python3-clufter + * liberation fonts (package liberation-sans-fonts or fonts-liberation or + fonts-liberation2) + * overpass fonts (package overpass-fonts) +diff --git a/configure.ac b/configure.ac +index 39ce5f36..60605c08 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -304,11 +304,6 @@ if test "$PYTHON_VERSION" = "3.6"; then + PCS_CHECK_PYMOD([dataclasses], [], [yes]) + fi + +-# python 3.8+ needs distro as well (removed from upstream lib) +-if printf '%s\n%s\n' "3.8" "$PYTHON_VERSION" | sort -V -C; then +- PCS_CHECK_PYMOD([distro], [], [yes]) +-fi +- + # special case, because we need to download from github + AC_PIP_MODULE([pyagentx]) + +diff --git a/mypy.ini b/mypy.ini +index 33d1e469..f3246735 100644 +--- a/mypy.ini ++++ b/mypy.ini +@@ -123,15 +123,9 @@ ignore_errors = True + + + # External libraries +-[mypy-clufter.*] +-ignore_missing_imports = True +- + [mypy-dacite] + ignore_missing_imports = True + +-[mypy-distro] +-ignore_missing_imports = True +- + [mypy-pyagentx] + ignore_errors = True + ignore_missing_imports = True +diff --git a/pcs/cli/common/parse_args.py b/pcs/cli/common/parse_args.py +index e3c829c7..767fdf7f 100644 +--- a/pcs/cli/common/parse_args.py ++++ b/pcs/cli/common/parse_args.py +@@ -27,8 +27,6 @@ PCS_LONG_OPTIONS = [ + "fullhelp", + "force", + "skip-offline", +- # TODO remove, deprecated command 'pcs config import-cman' +- "interactive", + "autodelete", + "simulate", + "all", +@@ -464,8 +462,6 @@ class InputModifiers: + # used only in deprecated 'pcs resource|stonith show' + "--groups": "--groups" in options, + "--hide-inactive": "--hide-inactive" in options, +- # TODO remove, deprecated command 'pcs config import-cman' +- "--interactive": "--interactive" in options, + "--local": "--local" in options, + "--master": "--master" in options, + "--monitor": "--monitor" in options, +diff --git a/pcs/cli/routing/config.py b/pcs/cli/routing/config.py +index 5d2663bd..7f878f4d 100644 +--- a/pcs/cli/routing/config.py ++++ b/pcs/cli/routing/config.py +@@ -21,20 +21,6 @@ config_cmd = create_router( + ["config", "checkpoint"], + default_cmd="list", + ), +- # TODO remove, deprecated command +- "import-cman": config.config_import_cman, +- # TODO remove, deprecated command +- "export": create_router( +- { +- "pcs-commands": config.config_export_pcs_commands, +- "pcs-commands-verbose": lambda lib, argv, modifiers: ( +- config.config_export_pcs_commands( +- lib, argv, modifiers, verbose=True +- ) +- ), +- }, +- ["config", "export"], +- ), + }, + ["config"], + default_cmd="show", +diff --git a/pcs/config.py b/pcs/config.py +index 8e37fc4b..521af8fd 100644 +--- a/pcs/config.py ++++ b/pcs/config.py +@@ -7,7 +7,6 @@ from io import BytesIO + import tarfile + import json + from xml.dom.minidom import parse +-import logging + import pwd + import grp + import tempfile +@@ -15,25 +14,6 @@ import time + import shutil + import difflib + +-try: +- import distro +- +- no_distro_package = False +-except ImportError: +- no_distro_package = True +- import platform +- +-# TODO remove, deprecated +-try: +- import clufter.facts +- import clufter.format_manager +- import clufter.filter_manager +- import clufter.command_manager +- +- no_clufter = False +-except ImportError: +- no_clufter = True +- + from pcs import ( + cluster, + constraint, +@@ -51,7 +31,6 @@ from pcs.cli.common.errors import CmdLineInputError + from pcs.cli.constraint import command as constraint_command + from pcs.cli.nvset import nvset_dto_list_to_lines + from pcs.cli.reports import process_library_reports +-from pcs.cli.reports.output import warn + from pcs.common.reports import constraints as constraints_reports + from pcs.common.str_tools import indent + from pcs.lib.commands import quorum as lib_quorum +@@ -807,359 +786,3 @@ def config_checkpoint_restore(lib, argv, modifiers): + except Exception as e: + utils.err("unable to read the checkpoint: %s" % e) + utils.replace_cib_configuration(snapshot_dom) +- +- +-# TODO remove, deprecated command +-def config_import_cman(lib, argv, modifiers): +- """ +- Options: +- * --force - skip checks, overwrite files +- * --interactive - interactive issue resolving +- * --request-timeout - effective only when ouput is not specified +- """ +- # pylint: disable=no-member +- del lib +- warn("This command is deprecated and will be removed.") +- modifiers.ensure_only_supported( +- "--force", +- "interactive", +- "--request-timeout", +- ) +- if no_clufter: +- utils.err( +- "Unable to perform a CMAN cluster conversion due to missing " +- "python-clufter package" +- ) +- clufter_supports_corosync3 = hasattr(clufter.facts, "cluster_pcs_camelback") +- +- # prepare convertor options +- cluster_conf = settings.cluster_conf_file +- dry_run_output = None +- output_format = "corosync.conf" +- dist = None +- invalid_args = False +- for arg in argv: +- if "=" in arg: +- name, value = arg.split("=", 1) +- if name == "input": +- cluster_conf = value +- elif name == "output": +- dry_run_output = value +- elif name == "output-format": +- if value in ( +- "corosync.conf", +- "pcs-commands", +- "pcs-commands-verbose", +- ): +- output_format = value +- else: +- invalid_args = True +- elif name == "dist": +- dist = value +- else: +- invalid_args = True +- else: +- invalid_args = True +- if output_format not in ("pcs-commands", "pcs-commands-verbose") and ( +- dry_run_output and not dry_run_output.endswith(".tar.bz2") +- ): +- dry_run_output += ".tar.bz2" +- if invalid_args or not dry_run_output: +- usage.config(["import-cman"]) +- sys.exit(1) +- debug = modifiers.get("--debug") +- force = modifiers.get("--force") +- interactive = modifiers.get("--interactive") +- +- if dist is not None: +- if not clufter_supports_corosync3: +- utils.err( +- "Unable to perform a CMAN cluster conversion due to clufter " +- "not supporting Corosync 3. Please, upgrade clufter packages." +- ) +- if not clufter.facts.cluster_pcs_camelback("linux", dist.split(",")): +- utils.err("dist does not match output-format") +- elif output_format == "corosync.conf": +- dist = _get_linux_dist() +- else: +- # for output-format=pcs-command[-verbose] +- dist = _get_linux_dist() +- +- clufter_args = { +- "input": str(cluster_conf), +- "cib": {"passin": "bytestring"}, +- "nocheck": force, +- "batch": True, +- "sys": "linux", +- "dist": dist, +- } +- if interactive: +- if "EDITOR" not in os.environ: +- utils.err("$EDITOR environment variable is not set") +- clufter_args["batch"] = False +- clufter_args["editor"] = os.environ["EDITOR"] +- if debug: +- logging.getLogger("clufter").setLevel(logging.DEBUG) +- if output_format == "corosync.conf": +- clufter_args["coro"] = {"passin": "struct"} +- cmd_name = "ccs2pcs-camelback" +- elif output_format in ("pcs-commands", "pcs-commands-verbose"): +- clufter_args["output"] = {"passin": "bytestring"} +- clufter_args["start_wait"] = "60" +- clufter_args["tmp_cib"] = "tmp-cib.xml" +- clufter_args["force"] = force +- clufter_args["text_width"] = "80" +- clufter_args["silent"] = True +- clufter_args["noguidance"] = True +- if output_format == "pcs-commands-verbose": +- clufter_args["text_width"] = "-1" +- clufter_args["silent"] = False +- clufter_args["noguidance"] = False +- if clufter.facts.cluster_pcs_flatiron("linux", dist.split(",")): +- cmd_name = "ccs2pcscmd-flatiron" +- elif clufter.facts.cluster_pcs_needle("linux", dist.split(",")): +- cmd_name = "ccs2pcscmd-needle" +- elif clufter_supports_corosync3 and clufter.facts.cluster_pcs_camelback( +- "linux", dist.split(",") +- ): +- cmd_name = "ccs2pcscmd-camelback" +- else: +- utils.err( +- "unrecognized dist, try something recognized" +- + " (e. g. rhel,6.8 or redhat,7.3 or debian,7 or ubuntu,trusty)" +- ) +- clufter_args_obj = type(str("ClufterOptions"), (object,), clufter_args) +- +- # run convertor +- run_clufter( +- cmd_name, +- clufter_args_obj, +- debug, +- force, +- "Error: unable to import cluster configuration", +- ) +- +- # save commands +- if output_format in ("pcs-commands", "pcs-commands-verbose"): +- ok, message = utils.write_file( +- dry_run_output, clufter_args_obj.output["passout"].decode() +- ) +- if not ok: +- utils.err(message) +- return +- +- # put new config files into tarball +- file_list = config_backup_path_list() +- for file_item in file_list.values(): +- file_item["attrs"]["uname"] = "root" +- file_item["attrs"]["gname"] = "root" +- file_item["attrs"]["uid"] = 0 +- file_item["attrs"]["gid"] = 0 +- file_item["attrs"]["mode"] = 0o600 +- tar_data = BytesIO() +- try: +- with tarfile.open(fileobj=tar_data, mode="w|bz2") as tarball: +- config_backup_add_version_to_tarball(tarball) +- utils.tar_add_file_data( +- tarball, +- clufter_args_obj.cib["passout"], +- "cib.xml", +- **file_list["cib.xml"]["attrs"], +- ) +- # put uidgid into separate files +- fmt_simpleconfig = clufter.format_manager.FormatManager.init_lookup( +- "simpleconfig" +- ).plugins["simpleconfig"] +- corosync_struct = [] +- uidgid_list = [] +- for section in clufter_args_obj.coro["passout"][2]: +- if section[0] == "uidgid": +- uidgid_list.append(section[1]) +- else: +- corosync_struct.append(section) +- corosync_conf_data = fmt_simpleconfig( +- "struct", ("corosync", (), corosync_struct) +- )("bytestring") +- utils.tar_add_file_data( +- tarball, +- corosync_conf_data, +- "corosync.conf", +- **file_list["corosync.conf"]["attrs"], +- ) +- for uidgid in uidgid_list: +- uid = "" +- gid = "" +- for item in uidgid: +- if item[0] == "uid": +- uid = item[1] +- if item[0] == "gid": +- gid = item[1] +- filename = utils.get_uid_gid_file_name(uid, gid) +- uidgid_data = fmt_simpleconfig( +- "struct", ("corosync", (), [("uidgid", uidgid, None)]) +- )("bytestring") +- utils.tar_add_file_data( +- tarball, +- uidgid_data, +- "uidgid.d/" + filename, +- **file_list["uidgid.d"]["attrs"], +- ) +- except (tarfile.TarError, EnvironmentError) as e: +- utils.err("unable to create tarball: %s" % e) +- tar_data.seek(0) +- +- # save tarball / remote restore +- if dry_run_output: +- ok, message = utils.write_file( +- dry_run_output, tar_data.read(), permissions=0o600, binary=True +- ) +- if not ok: +- utils.err(message) +- else: +- config_restore_remote(None, tar_data) +- tar_data.close() +- +- +-def _get_linux_dist(): +- if no_distro_package: +- # For Python 3.8+, python3-distro is a required dependency and we +- # should never get here. Pylint, of course, cannot know that. +- # pylint: disable=deprecated-method +- # pylint: disable=no-member +- distribution = platform.linux_distribution(full_distribution_name=False) +- else: +- distribution = distro.linux_distribution(full_distribution_name=False) +- return ",".join(distribution) +- +- +-# TODO remove, deprecated command +-def config_export_pcs_commands(lib, argv, modifiers, verbose=False): +- """ +- Options: +- * --force - skip checks, overwrite files +- * --interactive - interactive issue resolving +- * -f - CIB file +- * --corosync_conf +- """ +- del lib +- warn("This command is deprecated and will be removed.") +- modifiers.ensure_only_supported( +- "--force", "--interactive", "-f", "--corosync_conf" +- ) +- if no_clufter: +- utils.err( +- "Unable to perform export due to missing python-clufter package" +- ) +- +- # parse options +- debug = modifiers.get("--debug") +- force = modifiers.get("--force") +- interactive = modifiers.get("--interactive") +- invalid_args = False +- output_file = None +- dist = None +- for arg in argv: +- if "=" in arg: +- name, value = arg.split("=", 1) +- if name == "output": +- output_file = value +- elif name == "dist": +- dist = value +- else: +- invalid_args = True +- else: +- invalid_args = True +- # check options +- if invalid_args: +- usage.config(["export pcs-commands"]) +- sys.exit(1) +- # complete optional options +- if dist is None: +- dist = _get_linux_dist() +- +- # prepare convertor options +- clufter_args = { +- "nocheck": force, +- "batch": True, +- "sys": "linux", +- "dist": dist, +- "coro": settings.corosync_conf_file, +- "start_wait": "60", +- "tmp_cib": "tmp-cib.xml", +- "force": force, +- "text_width": "80", +- "silent": True, +- "noguidance": True, +- } +- if output_file: +- clufter_args["output"] = {"passin": "bytestring"} +- else: +- clufter_args["output"] = "-" +- if interactive: +- if "EDITOR" not in os.environ: +- utils.err("$EDITOR environment variable is not set") +- clufter_args["batch"] = False +- clufter_args["editor"] = os.environ["EDITOR"] +- if debug: +- logging.getLogger("clufter").setLevel(logging.DEBUG) +- if utils.usefile: +- clufter_args["cib"] = os.path.abspath(utils.filename) +- else: +- clufter_args["cib"] = ("bytestring", utils.get_cib()) +- if verbose: +- clufter_args["text_width"] = "-1" +- clufter_args["silent"] = False +- clufter_args["noguidance"] = False +- clufter_args_obj = type(str("ClufterOptions"), (object,), clufter_args) +- cmd_name = "pcs2pcscmd-camelback" +- +- # run convertor +- run_clufter( +- cmd_name, +- clufter_args_obj, +- debug, +- force, +- "Error: unable to export cluster configuration", +- ) +- +- # save commands if not printed to stdout by clufter +- if output_file: +- # pylint: disable=no-member +- ok, message = utils.write_file( +- output_file, clufter_args_obj.output["passout"].decode() +- ) +- if not ok: +- utils.err(message) +- +- +-# TODO remove, deprecated +-def run_clufter(cmd_name, cmd_args, debug, force, err_prefix): +- """ +- Commandline options: no options used but messages which include --force, +- --debug and --interactive are generated +- """ +- # pylint: disable=broad-except +- try: +- result = None +- cmd_manager = clufter.command_manager.CommandManager.init_lookup( +- cmd_name +- ) +- result = cmd_manager.commands[cmd_name](cmd_args) +- error_message = "" +- except Exception as e: +- error_message = str(e) +- if error_message or result != 0: +- hints = [] +- hints.append("--interactive to solve the issues manually") +- if not debug: +- hints.append("--debug to get more information") +- if not force: +- hints.append("--force to override") +- hints_string = "\nTry using %s." % ", ".join(hints) if hints else "" +- sys.stderr.write( +- err_prefix +- + (": %s" % error_message if error_message else "") +- + hints_string +- + "\n" +- ) +- sys.exit(1 if result is None else result) +diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in +index 205fdc4e..b72c2197 100644 +--- a/pcs/pcs.8.in ++++ b/pcs/pcs.8.in +@@ -1382,5 +1382,3 @@ http://clusterlabs.org/doc/ + + .BR boothd (8), + .BR sbd (8) +- +-.BR clufter (1) +diff --git a/pcs/settings.py.in b/pcs/settings.py.in +index 6df12997..68b18a53 100644 +--- a/pcs/settings.py.in ++++ b/pcs/settings.py.in +@@ -31,9 +31,6 @@ pcsd_token_max_bytes = 256 + booth_authkey_file_mode = 0o600 + # Booth does not support keys longer than 64 bytes. + booth_authkey_bytes = 64 +-# cluster conf is obsoleted and didn't support out-of-tree installation / run +-# hence it can stay hardcoded +-cluster_conf_file = "/etc/cluster/cluster.conf" + fence_agent_binaries = "@FASEXECPREFIX@/sbin" + pacemaker_local_state_dir = os.path.join( + "/", "@PCMKLOCALSTATEDIR@", "lib/pacemaker" +diff --git a/pcs_test/Makefile.am b/pcs_test/Makefile.am +index 7cd077f3..b73eb40c 100644 +--- a/pcs_test/Makefile.am ++++ b/pcs_test/Makefile.am +@@ -23,7 +23,6 @@ EXTRA_DIST = \ + resources/cib-largefile.xml \ + resources/cib-large.xml \ + resources/cib-tags.xml \ +- resources/cluster.conf \ + resources/corosync-3nodes.conf \ + resources/corosync-3nodes-qdevice.conf \ + resources/corosync-3nodes-qdevice-heuristics.conf \ +diff --git a/pcs_test/resources/cluster.conf b/pcs_test/resources/cluster.conf +deleted file mode 100644 +index 19889712..00000000 +--- a/pcs_test/resources/cluster.conf ++++ /dev/null +@@ -1,27 +0,0 @@ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +diff --git a/pcs_test/tier0/cli/common/test_parse_args.py b/pcs_test/tier0/cli/common/test_parse_args.py +index 493461bd..2739a9d3 100644 +--- a/pcs_test/tier0/cli/common/test_parse_args.py ++++ b/pcs_test/tier0/cli/common/test_parse_args.py +@@ -603,8 +603,6 @@ class InputModifiersTest(TestCase): + # used only in deprecated 'pcs resource|stonith show' + "--groups", + "--hide-inactive", +- # TODO remove, deprecated command 'pcs config import-cman' +- "--interactive", + "--local", + "--master", + "--monitor", +diff --git a/pcsd/Makefile.am b/pcsd/Makefile.am +index 007d2194..0cd2e90d 100644 +--- a/pcsd/Makefile.am ++++ b/pcsd/Makefile.am +@@ -2,7 +2,6 @@ EXTRA_DIST = \ + pam/pcsd.debian \ + pam/pcsd.fedora \ + test/cib1.xml \ +- test/cluster.conf \ + test/corosync.conf \ + test/crm1.xml \ + test/crm2.xml \ +diff --git a/pcsd/test/cluster.conf b/pcsd/test/cluster.conf +deleted file mode 100644 +index 19889712..00000000 +--- a/pcsd/test/cluster.conf ++++ /dev/null +@@ -1,27 +0,0 @@ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +diff --git a/rpm/pcs.spec.in b/rpm/pcs.spec.in +index 918986e0..f421bc53 100644 +--- a/rpm/pcs.spec.in ++++ b/rpm/pcs.spec.in +@@ -36,10 +36,6 @@ Summary: Pacemaker Configuration System + %define dataclasses_required 1 + %endif + +-%if "%{python3_version}" >= "3.8" +-%define distro_required 1 +-%endif +- + # mangling shebang in /usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/test from /usr/bin/env ruby to #!/usr/bin/ruby + #*** ERROR: ./usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/test.ru has shebang which doesn't start with '/' (../../bin/rackup) + #mangling shebang in /usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/rackup_stub.rb from /usr/bin/env ruby to #!/usr/bin/ruby +@@ -105,14 +101,6 @@ Requires: python3-cryptography + Requires: python3-lxml + Requires: python3-pycurl + Requires: python3-pyparsing +-%if 0%{?fedora} <= 32 +-# clufter and its dependencies +-Requires: python3-clufter => 0.70.0 +-%endif +-%if 0%{?rhel} < 9 +-# clufter and its dependencies +-Requires: python3-clufter => 0.70.0 +-%endif + # ruby and gems for pcsd + Requires: ruby >= 2.2.0 + Requires: rubygems +@@ -140,9 +128,6 @@ Recommends: overpass-fonts + %if %{defined dataclasses_required} + @pydataclassesbundle@ + %endif +-%if %{defined distro_required} +-@pydistrobundle@ +-%endif + + @gembundle@ + +-- +2.31.1 + diff --git a/bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch b/bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch deleted file mode 100644 index 6f2ad2d..0000000 --- a/bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch +++ /dev/null @@ -1,702 +0,0 @@ -From 68157f21fe8051ebd7eace11012738d8d91a1812 Mon Sep 17 00:00:00 2001 -From: Tomas Jelinek -Date: Tue, 2 Mar 2021 14:47:27 +0100 -Subject: [PATCH 1/2] squash bz1927404: replace pyOpenSSL with - python-cryptography - -python-cryptography requires new mypy - -improve TLS certificate verification - -Library methods are now used instead of running openssl processes. That -enabled support for Elliptic Curve certificates. - -cleanup dependencies in spec file ---- - .gitlab-ci.yml | 6 +- - README.md | 2 +- - mypy.ini | 7 +- - pcs.spec.in | 5 +- - pcs/common/ssl.py | 108 +++++++++++++++++------------- - pcs/daemon/ssl.py | 48 ++----------- - pcs/pcsd.py | 19 +++--- - pcs/utils.py | 32 --------- - pcs_test/tier0/daemon/test_ssl.py | 64 +++++++++--------- - pcsd/pcs.rb | 39 ++++------- - pcsd/remote.rb | 2 +- - requirements.txt | 2 +- - test/centos8/Dockerfile | 2 +- - test/fedora31/Dockerfile | 2 +- - test/fedora32/Dockerfile | 2 +- - 15 files changed, 135 insertions(+), 205 deletions(-) - -diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml -index 4cb4c14b..72668787 100644 ---- a/.gitlab-ci.yml -+++ b/.gitlab-ci.yml -@@ -46,12 +46,12 @@ pylint: - script: - - "dnf install -y - python3 -+ python3-cryptography - python3-dateutil - python3-distro - python3-lxml - python3-pip - python3-pycurl -- python3-pyOpenSSL - python3-pyparsing - findutils - make -@@ -66,12 +66,12 @@ mypy: - script: - - "dnf install -y - python3 -+ python3-cryptography - python3-dateutil - python3-distro - python3-lxml - python3-pip - python3-pycurl -- python3-pyOpenSSL - python3-pyparsing - git - make -@@ -111,12 +111,12 @@ python_tier0_tests: - - "dnf install -y - make - python3 -+ python3-cryptography - python3-dateutil - python3-distro - python3-lxml - python3-pip - python3-pycurl -- python3-pyOpenSSL - python3-pyparsing - which - " -diff --git a/README.md b/README.md -index fe6eeed6..a0c01c02 100644 ---- a/README.md -+++ b/README.md -@@ -30,7 +30,7 @@ These are the runtime dependencies of pcs and pcsd: - * python3-lxml - * python3-pycurl - * python3-setuptools --* python3-pyOpenSSL (python3-openssl) -+* python3-cryptography - * python3-pyparsing - * python3-tornado 6.1.0+ - * python dataclasses (`pip install dataclasses`; required only for python 3.6, -diff --git a/mypy.ini b/mypy.ini -index 6d3d2ff9..e3198530 100644 ---- a/mypy.ini -+++ b/mypy.ini -@@ -48,6 +48,10 @@ disallow_untyped_defs = True - # this is a temporary solution for legacy code - disallow_untyped_defs = False - -+[mypy-pcs.common.ssl] -+disallow_untyped_defs = True -+disallow_untyped_calls = True -+ - [mypy-pcs.common.types] - disallow_untyped_defs = True - disallow_untyped_calls = True -@@ -122,9 +126,6 @@ ignore_missing_imports = True - [mypy-distro] - ignore_missing_imports = True - --[mypy-OpenSSL] --ignore_missing_imports = True -- - [mypy-pyagentx.*] - ignore_errors = True - -diff --git a/pcs.spec.in b/pcs.spec.in -index db66c5b0..610fad50 100644 ---- a/pcs.spec.in -+++ b/pcs.spec.in -@@ -139,6 +139,7 @@ BuildRequires: python3-setuptools_scm - - BuildRequires: python3-devel - # for tier0 tests -+BuildRequires: python3-cryptography - BuildRequires: python3-pyparsing - - # gcc for compiling custom rubygems -@@ -171,6 +172,7 @@ Requires: platform-python - Requires: platform-python-setuptools - %endif - -+Requires: python3-cryptography - Requires: python3-lxml - Requires: python3-pycurl - Requires: python3-pyparsing -@@ -190,9 +192,6 @@ Requires: ruby >= 2.2.0 - Requires: rubygems - # for killall - Requires: psmisc --# for working with certificates (validation etc.) --Requires: openssl --Requires: python3-pyOpenSSL - # cluster stack and related packages - Requires: pacemaker >= 2.0.0 - Requires: corosync >= 3.0 -diff --git a/pcs/common/ssl.py b/pcs/common/ssl.py -index 852fea80..74ddd4ec 100644 ---- a/pcs/common/ssl.py -+++ b/pcs/common/ssl.py -@@ -1,45 +1,63 @@ --import time --from OpenSSL import crypto -- -- --def cert_date_format(timestamp): -- return str.encode(time.strftime("%Y%m%d%H%M%SZ", time.gmtime(timestamp))) -- -- --def generate_key(length=3072): -- key = crypto.PKey() -- key.generate_key(crypto.TYPE_RSA, length) -- return key -- -- --def generate_cert(key, server_name): -- now = time.time() -- cert = crypto.X509() -- -- subject = cert.get_subject() -- subject.countryName = "US" -- subject.stateOrProvinceName = "MN" -- subject.localityName = "Minneapolis" -- subject.organizationName = "pcsd" -- subject.organizationalUnitName = "pcsd" -- subject.commonName = server_name -- -- cert.set_version(2) -- cert.set_serial_number(int(now * 1000)) -- cert.set_notBefore(cert_date_format(now)) -- cert.set_notAfter( -- cert_date_format(now + 60 * 60 * 24 * 365 * 10) -- ) # 10 years -- cert.set_issuer(subject) -- cert.set_pubkey(key) -- cert.sign(key, "sha256") -- -- return cert -- -- --def dump_cert(certificate): -- return crypto.dump_certificate(crypto.FILETYPE_PEM, certificate) -- -- --def dump_key(key): -- return crypto.dump_privatekey(crypto.FILETYPE_PEM, key) -+import datetime -+import ssl -+from typing import List -+ -+from cryptography import x509 -+from cryptography.x509.oid import NameOID -+from cryptography.hazmat.backends import default_backend -+from cryptography.hazmat.primitives import hashes, serialization -+from cryptography.hazmat.primitives.asymmetric import rsa -+ -+ -+def check_cert_key(cert_path: str, key_path: str) -> List[str]: -+ errors = [] -+ try: -+ ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) -+ ssl_context.load_cert_chain(cert_path, key_path) -+ except ssl.SSLError as e: -+ errors.append(f"SSL certificate does not match the key: {e}") -+ except EnvironmentError as e: -+ errors.append(f"Unable to load SSL certificate and/or key: {e}") -+ return errors -+ -+ -+def generate_key(length: int = 3072) -> rsa.RSAPrivateKeyWithSerialization: -+ return rsa.generate_private_key( -+ public_exponent=65537, key_size=length, backend=default_backend() -+ ) -+ -+ -+def generate_cert(key: rsa.RSAPrivateKey, server_name: str) -> x509.Certificate: -+ now = datetime.datetime.utcnow() -+ subject = x509.Name( -+ [ -+ x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), -+ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "MN"), -+ x509.NameAttribute(NameOID.LOCALITY_NAME, "Minneapolis"), -+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "pcsd"), -+ x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "pcsd"), -+ x509.NameAttribute(NameOID.COMMON_NAME, server_name), -+ ] -+ ) -+ return ( -+ x509.CertificateBuilder() -+ .subject_name(subject) -+ .issuer_name(subject) -+ .public_key(key.public_key()) -+ .serial_number(int(now.timestamp() * 1000)) -+ .not_valid_before(now) -+ .not_valid_after(now + datetime.timedelta(days=3650)) -+ .sign(key, hashes.SHA256(), default_backend()) -+ ) -+ -+ -+def dump_cert(certificate: x509.Certificate) -> bytes: -+ return certificate.public_bytes(serialization.Encoding.PEM) -+ -+ -+def dump_key(key: rsa.RSAPrivateKeyWithSerialization) -> bytes: -+ return key.private_bytes( -+ serialization.Encoding.PEM, -+ serialization.PrivateFormat.TraditionalOpenSSL, -+ serialization.NoEncryption(), -+ ) -diff --git a/pcs/daemon/ssl.py b/pcs/daemon/ssl.py -index 40cca314..43865631 100644 ---- a/pcs/daemon/ssl.py -+++ b/pcs/daemon/ssl.py -@@ -1,9 +1,8 @@ - import os - import ssl - --from OpenSSL import crypto, SSL -- - from pcs.common.ssl import ( -+ check_cert_key, - dump_cert, - dump_key, - generate_cert, -@@ -11,53 +10,15 @@ from pcs.common.ssl import ( - ) - - --def check_cert_key(cert_path, key_path): -- errors = [] -- -- def load(load_ssl_file, label, path): -- try: -- with open(path) as ssl_file: -- return load_ssl_file(crypto.FILETYPE_PEM, ssl_file.read()) -- except EnvironmentError as e: -- errors.append(f"Unable to read SSL {label} '{path}': '{e}'") -- except crypto.Error as e: -- msg = "" -- if e.args and e.args[0] and e.args[0][0]: -- msg = f": '{':'.join(e.args[0][0])}'" -- errors.append(f"Invalid SSL {label} '{path}'{msg}") -- -- cert = load(crypto.load_certificate, "certificate", cert_path) -- key = load(crypto.load_privatekey, "key", key_path) -- -- if errors: -- return errors -- -- try: -- context = SSL.Context(SSL.TLSv1_METHOD) -- context.use_privatekey(key) -- context.use_certificate(cert) -- except SSL.Error as e: -- errors.append(f"Unable to load SSL certificate and/or key: {e}") -- # If we cannot load the files, do not confuse users with other error -- # messages. -- return errors -- try: -- context.check_privatekey() -- except (crypto.Error, SSL.Error) as e: -- errors.append(f"SSL certificate does not match the key: {e}") -- -- return errors -- -- --def open_ssl_file_to_rewrite(path): -+def _open_ssl_file_to_rewrite(path): - return os.fdopen(os.open(path, os.O_CREAT | os.O_WRONLY, 0o600), "wb") - - - def regenerate_cert_key(server_name, cert_path, key_path, key_length=None): - key = generate_key(key_length) if key_length else generate_key() -- with open_ssl_file_to_rewrite(cert_path) as cert_file: -+ with _open_ssl_file_to_rewrite(cert_path) as cert_file: - cert_file.write(dump_cert(generate_cert(key, server_name))) -- with open_ssl_file_to_rewrite(key_path) as key_file: -+ with _open_ssl_file_to_rewrite(key_path) as key_file: - key_file.write(dump_key(key)) - - -@@ -102,7 +63,6 @@ class PcsdSSL: - self.__ck_pair = CertKeyPair(cert_location, key_location) - - def create_context(self) -> ssl.SSLContext: -- # pylint: disable=no-member - ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) - ssl_context.set_ciphers(self.__ssl_ciphers) - ssl_context.options = self.__ssl_options -diff --git a/pcs/pcsd.py b/pcs/pcsd.py -index f3e6bca3..d5ddb443 100644 ---- a/pcs/pcsd.py -+++ b/pcs/pcsd.py -@@ -5,6 +5,7 @@ import sys - from pcs import settings - from pcs import utils - from pcs.cli.common.errors import CmdLineInputError -+import pcs.common.ssl - - - def pcsd_certkey(lib, argv, modifiers): -@@ -21,13 +22,13 @@ def pcsd_certkey(lib, argv, modifiers): - keyfile = argv[1] - - try: -- with open(certfile, "r") as myfile: -+ with open(certfile, "rb") as myfile: - cert = myfile.read() -- with open(keyfile, "r") as myfile: -+ with open(keyfile, "rb") as myfile: - key = myfile.read() - except IOError as e: - utils.err(e) -- errors = utils.verify_cert_key_pair(cert, key) -+ errors = pcs.common.ssl.check_cert_key(certfile, keyfile) - if errors: - for err in errors: - utils.err(err, False) -@@ -43,12 +44,12 @@ def pcsd_certkey(lib, argv, modifiers): - - try: - try: -- os.chmod(settings.pcsd_cert_location, 0o700) -+ os.chmod(settings.pcsd_cert_location, 0o600) - except OSError: # If the file doesn't exist, we don't care - pass - - try: -- os.chmod(settings.pcsd_key_location, 0o700) -+ os.chmod(settings.pcsd_key_location, 0o600) - except OSError: # If the file doesn't exist, we don't care - pass - -@@ -56,9 +57,9 @@ def pcsd_certkey(lib, argv, modifiers): - os.open( - settings.pcsd_cert_location, - os.O_WRONLY | os.O_CREAT | os.O_TRUNC, -- 0o700, -+ 0o600, - ), -- "w", -+ "wb", - ) as myfile: - myfile.write(cert) - -@@ -66,9 +67,9 @@ def pcsd_certkey(lib, argv, modifiers): - os.open( - settings.pcsd_key_location, - os.O_WRONLY | os.O_CREAT | os.O_TRUNC, -- 0o700, -+ 0o600, - ), -- "w", -+ "wb", - ) as myfile: - myfile.write(key) - -diff --git a/pcs/utils.py b/pcs/utils.py -index 97a04787..59d1b66e 100644 ---- a/pcs/utils.py -+++ b/pcs/utils.py -@@ -2105,38 +2105,6 @@ def is_iso8601_date(var): - return retVal == 0 - - --def verify_cert_key_pair(cert, key): -- """ -- Commandline options: no options -- """ -- errors = [] -- cert_modulus = "" -- key_modulus = "" -- -- output, retval = run( -- ["/usr/bin/openssl", "x509", "-modulus", "-noout"], -- string_for_stdin=cert, -- ) -- if retval != 0: -- errors.append("Invalid certificate: {0}".format(output.strip())) -- else: -- cert_modulus = output.strip() -- -- output, retval = run( -- ["/usr/bin/openssl", "rsa", "-modulus", "-noout"], string_for_stdin=key -- ) -- if retval != 0: -- errors.append("Invalid key: {0}".format(output.strip())) -- else: -- key_modulus = output.strip() -- -- if not errors and cert_modulus and key_modulus: -- if cert_modulus != key_modulus: -- errors.append("Certificate does not match the key") -- -- return errors -- -- - def err(errorText, exit_after_error=True): - sys.stderr.write("Error: %s\n" % errorText) - if exit_after_error: -diff --git a/pcs_test/tier0/daemon/test_ssl.py b/pcs_test/tier0/daemon/test_ssl.py -index e80f7a30..2b2edd36 100644 ---- a/pcs_test/tier0/daemon/test_ssl.py -+++ b/pcs_test/tier0/daemon/test_ssl.py -@@ -1,8 +1,7 @@ - import os -+import ssl - from unittest import mock, TestCase - --from OpenSSL import SSL -- - from pcs_test.tools.misc import get_tmp_dir - - from pcs.daemon.ssl import PcsdSSL, CertKeyPair, SSLCertKeyException -@@ -19,19 +18,6 @@ class SslFilesMixin: - self.ssl_dir = get_tmp_dir("tier0_daemon_ssl") - self.cert_path = os.path.join(self.ssl_dir.name, "daemon.cert") - self.key_path = os.path.join(self.ssl_dir.name, "daemon.key") -- # various versions of OpenSSL / PyOpenSSL emit different messages -- self.DAMAGED_SSL_FILES_ERRORS_1 = ( -- f"Invalid SSL certificate '{self.cert_path}':" -- " 'PEM routines:PEM_read_bio:no start line'", -- f"Invalid SSL key '{self.key_path}':" -- " 'PEM routines:PEM_read_bio:no start line'", -- ) -- self.DAMAGED_SSL_FILES_ERRORS_2 = ( -- f"Invalid SSL certificate '{self.cert_path}':" -- " 'PEM routines:get_name:no start line'", -- f"Invalid SSL key '{self.key_path}':" -- " 'PEM routines:get_name:no start line'", -- ) - - def tearDown(self): - # pylint cannot possibly know this is being mixed into TestCase classes -@@ -56,21 +42,31 @@ class Pair(SslFilesMixin, TestCase): - - def test_error_if_files_with_bad_content(self): - self.damage_ssl_files() -- self.assertTrue( -- self.pair.check() -- in [ -- list(self.DAMAGED_SSL_FILES_ERRORS_1), -- list(self.DAMAGED_SSL_FILES_ERRORS_2), -- ] -+ errors = self.pair.check() -+ self.assertEqual(len(errors), 1) -+ self.assertRegex( -+ errors[0], -+ r"^SSL certificate does not match the key: " -+ r"\[SSL\] PEM lib \(_ssl\.c:\d+\)", - ) - -- @mock.patch("pcs.daemon.ssl.SSL.Context.use_privatekey") -- def test_error_if_short_key(self, mock_use_key): -- mock_use_key.side_effect = SSL.Error("reason") -+ @mock.patch("pcs.daemon.ssl.ssl.SSLContext.load_cert_chain") -+ def test_error_if_short_key(self, mock_load_cert_chain): -+ mock_load_cert_chain.side_effect = ssl.SSLError( -+ # These are the real args of the exception. -+ 336245135, -+ "[SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:3542)", -+ ) -+ # 512 cannot be used as we would get an error from FIPS and 1024 is -+ # long enough. So a mock must be used. - self.pair.regenerate(SERVER_NAME, 1024) - errors = self.pair.check() - self.assertEqual( -- errors, ["Unable to load SSL certificate and/or key: reason"] -+ errors, -+ [ -+ "SSL certificate does not match the key: " -+ "[SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:3542)", -+ ], - ) - - def test_error_if_cert_does_not_match_key(self): -@@ -83,8 +79,10 @@ class Pair(SslFilesMixin, TestCase): - - errors = self.pair.check() - self.assertEqual(len(errors), 1) -- self.assertTrue( -- errors[0].startswith("SSL certificate does not match the key:") -+ self.assertRegex( -+ errors[0], -+ r"SSL certificate does not match the key: " -+ r"\[X509: KEY_VALUES_MISMATCH\] key values mismatch \(_ssl\.c:\d+\)", - ) - - -@@ -102,12 +100,12 @@ class PcsdSSLTest(SslFilesMixin, TestCase): - self.damage_ssl_files() - with self.assertRaises(SSLCertKeyException) as ctx_manager: - self.pcsd_ssl.guarantee_valid_certs() -- self.assertTrue( -- ctx_manager.exception.args -- in [ -- self.DAMAGED_SSL_FILES_ERRORS_1, -- self.DAMAGED_SSL_FILES_ERRORS_2, -- ] -+ errors = ctx_manager.exception.args -+ self.assertEqual(len(errors), 1) -+ self.assertRegex( -+ errors[0], -+ r"SSL certificate does not match the key: " -+ r"\[SSL\] PEM lib \(_ssl\.c:\d+\)", - ) - - def test_context_uses_given_options(self): -diff --git a/pcsd/pcs.rb b/pcsd/pcs.rb -index bce8e39e..89c26f33 100644 ---- a/pcsd/pcs.rb -+++ b/pcsd/pcs.rb -@@ -12,6 +12,7 @@ require 'fileutils' - require 'backports/latest' - require 'base64' - require 'ethon' -+require 'openssl' - - require 'config.rb' - require 'cfgsync.rb' -@@ -1170,39 +1171,23 @@ def read_file_lock(path, binary=false) - end - end - --def verify_cert_key_pair(cert, key) -+def verify_cert_key_pair(cert_data, key_data) - errors = [] -- cert_modulus = nil -- key_modulus = nil - -- stdout, stderr, retval = run_cmd_options( -- PCSAuth.getSuperuserAuth(), -- { -- 'stdin' => cert, -- }, -- '/usr/bin/openssl', 'x509', '-modulus', '-noout' -- ) -- if retval != 0 -- errors << "Invalid certificate: #{stderr.join}" -- else -- cert_modulus = stdout.join.strip -+ begin -+ cert = OpenSSL::X509::Certificate.new(cert_data) -+ rescue OpenSSL::X509::CertificateError => e -+ errors << "Invalid certificate: #{e}" - end - -- stdout, stderr, retval = run_cmd_options( -- PCSAuth.getSuperuserAuth(), -- { -- 'stdin' => key, -- }, -- '/usr/bin/openssl', 'rsa', '-modulus', '-noout' -- ) -- if retval != 0 -- errors << "Invalid key: #{stderr.join}" -- else -- key_modulus = stdout.join.strip -+ begin -+ key = OpenSSL::PKey.read(key_data) -+ rescue OpenSSL::PKey::PKeyError => e -+ errors << "Invalid key: #{e}" - end - -- if errors.empty? and cert_modulus and key_modulus -- if cert_modulus != key_modulus -+ if errors.empty? -+ if not cert.check_private_key(key) - errors << 'Certificate does not match the key' - end - end -diff --git a/pcsd/remote.rb b/pcsd/remote.rb -index 3361b3f6..c43e3116 100644 ---- a/pcsd/remote.rb -+++ b/pcsd/remote.rb -@@ -694,7 +694,7 @@ def set_certs(params, request, auth_user) - if !ssl_cert.empty? and !ssl_key.empty? - ssl_errors = verify_cert_key_pair(ssl_cert, ssl_key) - if ssl_errors and !ssl_errors.empty? -- return [400, ssl_errors.join] -+ return [400, ssl_errors.join('; ')] - end - begin - write_file_lock(CRT_FILE, 0600, ssl_cert) -diff --git a/requirements.txt b/requirements.txt -index eb42ce40..2f62b1c3 100644 ---- a/requirements.txt -+++ b/requirements.txt -@@ -2,7 +2,7 @@ - astroid==2.4.2 - pylint==2.6.0 - tornado>=6.1.0 --mypy==0.790 -+mypy==0.812 - dacite - # temporarily stick to previous version until it's convinient to reformat code - black==20.8b1 -diff --git a/test/centos8/Dockerfile b/test/centos8/Dockerfile -index 910d7652..00c17ffe 100644 ---- a/test/centos8/Dockerfile -+++ b/test/centos8/Dockerfile -@@ -7,11 +7,11 @@ RUN dnf install -y \ - --enablerepo=PowerTools \ - # python - python3 \ -+ python3-cryptography \ - python3-lxml \ - python3-mock \ - python3-pip \ - python3-pycurl \ -- python3-pyOpenSSL \ - python3-pyparsing \ - # ruby - ruby \ -diff --git a/test/fedora31/Dockerfile b/test/fedora31/Dockerfile -index cc94bee2..8d0a0672 100644 ---- a/test/fedora31/Dockerfile -+++ b/test/fedora31/Dockerfile -@@ -5,11 +5,11 @@ ARG src_path - RUN dnf install -y \ - # python - python3 \ -+ python3-cryptography \ - python3-lxml \ - python3-mock \ - python3-pip \ - python3-pycurl \ -- python3-pyOpenSSL \ - python3-pyparsing \ - # ruby - ruby \ -diff --git a/test/fedora32/Dockerfile b/test/fedora32/Dockerfile -index 82bdff74..750ff979 100644 ---- a/test/fedora32/Dockerfile -+++ b/test/fedora32/Dockerfile -@@ -5,12 +5,12 @@ ARG src_path - RUN dnf install -y \ - # python - python3 \ -+ python3-cryptography \ - python3-distro \ - python3-lxml \ - python3-mock \ - python3-pip \ - python3-pycurl \ -- python3-pyOpenSSL \ - python3-pyparsing \ - # ruby - ruby \ --- -2.26.2 - diff --git a/do-not-support-cluster-setup-with-udp-u-transport.patch b/do-not-support-cluster-setup-with-udp-u-transport.patch index db65252..f292a1e 100644 --- a/do-not-support-cluster-setup-with-udp-u-transport.patch +++ b/do-not-support-cluster-setup-with-udp-u-transport.patch @@ -1,19 +1,19 @@ -From 6c96d0fd135ca25204efeb5cb75e80053b26c6b1 Mon Sep 17 00:00:00 2001 +From 6f005e31d7ad18ac15b5b4b067e7a4561bc7251d Mon Sep 17 00:00:00 2001 From: Ivan Devat Date: Tue, 20 Nov 2018 15:03:56 +0100 -Subject: [PATCH 2/2] do not support cluster setup with udp(u) transport +Subject: [PATCH 3/3] do not support cluster setup with udp(u) transport --- - pcs/pcs.8 | 2 ++ + pcs/pcs.8.in | 2 ++ pcs/usage.py | 1 + pcsd/public/css/style.css | 3 +++ 3 files changed, 6 insertions(+) -diff --git a/pcs/pcs.8 b/pcs/pcs.8 -index edfdd039..8caf087f 100644 ---- a/pcs/pcs.8 -+++ b/pcs/pcs.8 -@@ -424,6 +424,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable +diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in +index b72c2197..841453fa 100644 +--- a/pcs/pcs.8.in ++++ b/pcs/pcs.8.in +@@ -420,6 +420,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable Transports udp and udpu: .br @@ -23,10 +23,10 @@ index edfdd039..8caf087f 100644 .br Transport options are: ip_version, netmtu diff --git a/pcs/usage.py b/pcs/usage.py -index baedb347..f576eaf2 100644 +index cec99ef2..30515ebb 100644 --- a/pcs/usage.py +++ b/pcs/usage.py -@@ -852,6 +852,7 @@ Commands: +@@ -853,6 +853,7 @@ Commands: hash=sha256. To disable encryption, set cipher=none and hash=none. Transports udp and udpu: @@ -35,7 +35,7 @@ index baedb347..f576eaf2 100644 support traffic encryption nor compression. Transport options are: diff --git a/pcsd/public/css/style.css b/pcsd/public/css/style.css -index b857cbae..b8d48d92 100644 +index 2f26e831..a7702ac4 100644 --- a/pcsd/public/css/style.css +++ b/pcsd/public/css/style.css @@ -949,6 +949,9 @@ table.args-table td.reg { @@ -49,5 +49,5 @@ index b857cbae..b8d48d92 100644 #csetup-transport-options.knet .without-knet { -- -2.26.2 +2.31.1 diff --git a/fix-wrong-name-for-library-command.patch b/fix-wrong-name-for-library-command.patch new file mode 100644 index 0000000..461e2e4 --- /dev/null +++ b/fix-wrong-name-for-library-command.patch @@ -0,0 +1,151 @@ +From e5781d95faae560f46ea56525d67eeb36b244a36 Mon Sep 17 00:00:00 2001 +From: Ivan Devat +Date: Thu, 10 Jun 2021 14:52:15 +0200 +Subject: [PATCH 1/3] fix wrong name for library command + +--- + pcs/cli/common/lib_wrapper.py | 8 ++++---- + pcs/cli/constraint_colocation/command.py | 2 +- + pcs/cli/constraint_order/command.py | 4 +++- + pcs/cli/constraint_ticket/command.py | 4 ++-- + pcs_test/tier0/cli/common/test_lib_wrapper.py | 6 +++--- + pcs_test/tier0/cli/constraint_ticket/test_command.py | 8 ++++---- + 6 files changed, 17 insertions(+), 15 deletions(-) + +diff --git a/pcs/cli/common/lib_wrapper.py b/pcs/cli/common/lib_wrapper.py +index d9a6bd26..c41ce875 100644 +--- a/pcs/cli/common/lib_wrapper.py ++++ b/pcs/cli/common/lib_wrapper.py +@@ -230,7 +230,7 @@ def load_module(env, middleware_factory, name): + env, + middleware.build(middleware_factory.cib), + { +- "set": constraint_colocation.create_with_set, ++ "create_with_set": constraint_colocation.create_with_set, + "show": constraint_colocation.show, + }, + ) +@@ -240,7 +240,7 @@ def load_module(env, middleware_factory, name): + env, + middleware.build(middleware_factory.cib), + { +- "set": constraint_order.create_with_set, ++ "create_with_set": constraint_order.create_with_set, + "show": constraint_order.show, + }, + ) +@@ -250,9 +250,9 @@ def load_module(env, middleware_factory, name): + env, + middleware.build(middleware_factory.cib), + { +- "set": constraint_ticket.create_with_set, ++ "create_with_set": constraint_ticket.create_with_set, + "show": constraint_ticket.show, +- "add": constraint_ticket.create, ++ "create": constraint_ticket.create, + "remove": constraint_ticket.remove, + }, + ) +diff --git a/pcs/cli/constraint_colocation/command.py b/pcs/cli/constraint_colocation/command.py +index f5cf91ab..10539aa6 100644 +--- a/pcs/cli/constraint_colocation/command.py ++++ b/pcs/cli/constraint_colocation/command.py +@@ -18,7 +18,7 @@ def create_with_set(lib, argv, modifiers): + """ + modifiers.ensure_only_supported("-f", "--force") + command.create_with_set( +- lib.constraint_colocation.set, ++ lib.constraint_colocation.create_with_set, + argv, + modifiers, + ) +diff --git a/pcs/cli/constraint_order/command.py b/pcs/cli/constraint_order/command.py +index 04a49c8e..7251a4a7 100644 +--- a/pcs/cli/constraint_order/command.py ++++ b/pcs/cli/constraint_order/command.py +@@ -17,7 +17,9 @@ def create_with_set(lib, argv, modifiers): + * -f - CIB file + """ + modifiers.ensure_only_supported("--force", "-f") +- command.create_with_set(lib.constraint_order.set, argv, modifiers) ++ command.create_with_set( ++ lib.constraint_order.create_with_set, argv, modifiers ++ ) + + + def show(lib, argv, modifiers): +diff --git a/pcs/cli/constraint_ticket/command.py b/pcs/cli/constraint_ticket/command.py +index 7823981e..b4cd2bcd 100644 +--- a/pcs/cli/constraint_ticket/command.py ++++ b/pcs/cli/constraint_ticket/command.py +@@ -20,7 +20,7 @@ def create_with_set(lib, argv, modifiers): + """ + modifiers.ensure_only_supported("--force", "-f") + command.create_with_set( +- lib.constraint_ticket.set, ++ lib.constraint_ticket.create_with_set, + argv, + modifiers, + ) +@@ -50,7 +50,7 @@ def add(lib, argv, modifiers): + if resource_role: + options["rsc-role"] = resource_role + +- lib.constraint_ticket.add( ++ lib.constraint_ticket.create( + ticket, + resource_id, + options, +diff --git a/pcs_test/tier0/cli/common/test_lib_wrapper.py b/pcs_test/tier0/cli/common/test_lib_wrapper.py +index 3a8188c6..33538685 100644 +--- a/pcs_test/tier0/cli/common/test_lib_wrapper.py ++++ b/pcs_test/tier0/cli/common/test_lib_wrapper.py +@@ -25,8 +25,8 @@ class LibraryWrapperTest(TestCase): + mock_middleware_factory.cib = dummy_middleware + mock_middleware_factory.corosync_conf_existing = dummy_middleware + mock_env = mock.MagicMock() +- Library(mock_env, mock_middleware_factory).constraint_order.set( +- "first", second="third" +- ) ++ Library( ++ mock_env, mock_middleware_factory ++ ).constraint_order.create_with_set("first", second="third") + + mock_order_set.assert_called_once_with(lib_env, "first", second="third") +diff --git a/pcs_test/tier0/cli/constraint_ticket/test_command.py b/pcs_test/tier0/cli/constraint_ticket/test_command.py +index 118bfa22..ca4835c3 100644 +--- a/pcs_test/tier0/cli/constraint_ticket/test_command.py ++++ b/pcs_test/tier0/cli/constraint_ticket/test_command.py +@@ -24,12 +24,12 @@ class AddTest(TestCase): + ) + lib = mock.MagicMock() + lib.constraint_ticket = mock.MagicMock() +- lib.constraint_ticket.add = mock.MagicMock() ++ lib.constraint_ticket.create = mock.MagicMock() + + command.add(lib, ["argv"], _modifiers()) + + mock_parse_add.assert_called_once_with(["argv"]) +- lib.constraint_ticket.add.assert_called_once_with( ++ lib.constraint_ticket.create.assert_called_once_with( + "ticket", + "resource_id", + {"loss-policy": "fence"}, +@@ -60,12 +60,12 @@ class AddTest(TestCase): + ) + lib = mock.MagicMock() + lib.constraint_ticket = mock.MagicMock() +- lib.constraint_ticket.add = mock.MagicMock() ++ lib.constraint_ticket.create = mock.MagicMock() + + command.add(lib, ["argv"], _modifiers()) + + mock_parse_add.assert_called_once_with(["argv"]) +- lib.constraint_ticket.add.assert_called_once_with( ++ lib.constraint_ticket.create.assert_called_once_with( + "ticket", + "resource_id", + {"loss-policy": "fence", "rsc-role": "resource_role"}, +-- +2.31.1 + diff --git a/pcs.spec b/pcs.spec index ef90d93..a4d9b69 100644 --- a/pcs.spec +++ b/pcs.spec @@ -1,6 +1,6 @@ Name: pcs Version: 0.10.8 -Release: 5%{?dist} +Release: 6%{?dist} # https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/ # https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses # GPLv2: pcs @@ -11,21 +11,21 @@ Release: 5%{?dist} # (GPLv2 or Ruby) and BSD: thin # BSD or Ruby: open4, rexml, ruby2_keywords, webrick # BSD and MIT: ffi -License: GPLv2 and ASL 2.0 and MIT and BSD and (GPLv2 or Ruby) and (BSD or Ruby) +License: GPLv2 and ASL 2.0 and MIT and BSD and (GPLv2 or Ruby) and (BSD or Ruby). URL: https://github.com/ClusterLabs/pcs Group: System Environment/Base Summary: Pacemaker Configuration System #building only for architectures with pacemaker and corosync available ExclusiveArch: i686 x86_64 s390x ppc64le aarch64 -%global version_or_commit %{version} -# %%global version_or_commit 508b3999eb02b4901e83b8e780af8422b522ad30 +# %%global version_or_commit %%{version} +%global version_or_commit %{version}.181-47e9 %global pcs_source_name %{name}-%{version_or_commit} # ui_commit can be determined by hash, tag or branch -%global ui_commit 0.1.5 -%global ui_modules_version 0.1.5 +%global ui_commit 0.1.6 +%global ui_modules_version 0.1.6 %global ui_src_name pcs-web-ui-%{ui_commit} %global pcs_snmp_pkg_name pcs-snmp @@ -44,7 +44,7 @@ ExclusiveArch: i686 x86_64 s390x ppc64le aarch64 %global version_rubygem_rack 2.2.3 %global version_rubygem_rack_protection 2.0.8.1 %global version_rubygem_rack_test 1.1.0 -%global version_rubygem_rexml 3.2.4 +%global version_rubygem_rexml 3.2.5 %global version_rubygem_ruby2_keywords 0.0.2 %global version_rubygem_sinatra 2.0.8.1 %global version_rubygem_thin 1.7.2 @@ -54,20 +54,13 @@ ExclusiveArch: i686 x86_64 s390x ppc64le aarch64 # javascript bundled libraries for old web-ui %global ember_version 1.4.0 %global handlebars_version 1.2.1 -%global jquery_ui_version 1.10.1 -%global jquery_version 1.9.1 +%global jquery_ui_version 1.12.1 +%global jquery_version 3.6.0 -# We do not use _libdir macro because upstream is not prepared for it. -# Pcs does not include binaries and thus it should live in /usr/lib. Tornado -# and gems include binaries and thus it should live in /usr/lib64. But the -# path to tornado/gems is hardcoded in pcs sources. Modify hard links in pcs -# sources is not the way since then rpmdiff complains that the same file has -# different content in different architectures. -%global pcs_libdir %{_prefix}/lib -%global bundled_src_dir pcs/bundled +%global pcs_bundled_dir pcs_bundled %global pcsd_public_dir pcsd/public -%global rubygem_cache_dir pcsd/vendor/cache -%global rubygem_bundle_dir pcsd/vendor/bundle/ruby +%global rubygem_bundle_dir pcsd/vendor/bundle +%global rubygem_cache_dir %{rubygem_bundle_dir}/cache # mangling shebang in /usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/test from /usr/bin/env ruby to #!/usr/bin/ruby #*** ERROR: ./usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/test.ru has shebang which doesn't start with '/' (../../bin/rackup) @@ -86,7 +79,6 @@ ExclusiveArch: i686 x86_64 s390x ppc64le aarch64 Source0: %{url}/archive/%{version_or_commit}/%{pcs_source_name}.tar.gz Source1: HAM-logo.png -Source2: pcsd-bundle-config-2 Source41: https://github.com/ondrejmular/pyagentx/archive/v%{pyagentx_version}/pyagentx-%{pyagentx_version}.tar.gz Source42: https://github.com/tornadoweb/tornado/archive/v%{tornado_version}/tornado-%{tornado_version}.tar.gz @@ -96,6 +88,7 @@ Source81: https://rubygems.org/downloads/backports-%{version_rubygem_backports}. Source82: https://rubygems.org/downloads/ethon-%{version_rubygem_ethon}.gem Source83: https://rubygems.org/downloads/ffi-%{version_rubygem_ffi}.gem Source84: https://rubygems.org/downloads/json-%{version_rubygem_json}.gem +Source85: https://rubygems.org/downloads/rexml-%{version_rubygem_rexml}.gem Source86: https://rubygems.org/downloads/mustermann-%{version_rubygem_mustermann}.gem # We needed to re-upload open4 rubygem because of issues with sources in gating. # Unfortunately, there was no newer version available, therefore we had to @@ -110,18 +103,18 @@ Source93: https://rubygems.org/downloads/eventmachine-%{version_rubygem_eventmac Source94: https://rubygems.org/downloads/daemons-%{version_rubygem_daemons}.gem Source95: https://rubygems.org/downloads/thin-%{version_rubygem_thin}.gem Source96: https://rubygems.org/downloads/ruby2_keywords-%{version_rubygem_ruby2_keywords}.gem -Source97: https://rubygems.org/downloads/rexml-%{version_rubygem_rexml}.gem -Source98: https://rubygems.org/downloads/webrick-%{version_rubygem_webrick}.gem +Source97: https://rubygems.org/downloads/webrick-%{version_rubygem_webrick}.gem Source100: https://github.com/idevat/pcs-web-ui/archive/%{ui_commit}/%{ui_src_name}.tar.gz -Source101: https://github.com/idevat/pcs-web-ui/releases/download/%{ui_modules_version}/pcs-web-ui-node-modules-%{ui_modules_version}.fix.1.tar.xz +Source101: https://github.com/idevat/pcs-web-ui/releases/download/%{ui_modules_version}/pcs-web-ui-node-modules-%{ui_modules_version}.tar.xz # Patches from upstream. # They should come before downstream patches to avoid unnecessary conflicts. # Z-streams are exception here: they can come from upstream but should be # applied at the end to keep z-stream changes as straightforward as possible. # Patch1: bzNUMBER-01-name.patch -Patch1: bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch +Patch1: fix-wrong-name-for-library-command.patch +Patch2: bz1881064-01-remove-clufter-commands.patch # Downstream patches do not come from upstream. They adapt pcs for specific # RHEL needs. @@ -138,7 +131,14 @@ BuildRequires: python3-dateutil >= 2.7.0 BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: python3-pycurl +BuildRequires: python3-pip BuildRequires: python3-pyparsing +BuildRequires: python3-cryptography +BuildRequires: python3-lxml +# for building bundled python packages +BuildRequires: python3-wheel +# for bundled python dateutil +BuildRequires: python3-setuptools_scm # gcc for compiling custom rubygems BuildRequires: gcc BuildRequires: gcc-c++ @@ -146,14 +146,13 @@ BuildRequires: gcc-c++ BuildRequires: ruby >= 2.2.0 BuildRequires: ruby-devel BuildRequires: rubygems +BuildRequires: rubygem-bundler # ruby libraries for tests BuildRequires: rubygem-test-unit # for touching patch files (sanitization function) BuildRequires: diffstat # for post, preun and postun macros BuildRequires: systemd -# for tests -BuildRequires: python3-lxml # pcsd fonts and font management tools for creating symlinks to fonts BuildRequires: fontconfig BuildRequires: liberation-sans-fonts @@ -165,6 +164,15 @@ BuildRequires: redhat-logos # for building web ui BuildRequires: npm +# cluster stack packages for pkg-config +BuildRequires: booth +BuildRequires: corosync-qdevice-devel +BuildRequires: corosynclib-devel >= 3.0 +BuildRequires: fence-agents-common +BuildRequires: pacemaker-libs-devel >= 2.0.0 +BuildRequires: resource-agents +BuildRequires: sbd + # python and libraries for pcs, setuptools for pcs entrypoint Requires: python3 >= 3.6 Requires: python3-cryptography @@ -173,6 +181,7 @@ Requires: python3-lxml Requires: python3-setuptools Requires: python3-pycurl Requires: python3-pyparsing +Requires: python3-cryptography # ruby and gems for pcsd Requires: ruby >= 2.2.0 Requires: rubygems @@ -237,7 +246,7 @@ Summary: Pacemaker cluster SNMP agent # https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses # GPLv2: pcs # BSD-2-Clause: pyagentx -License: GPLv2 and BSD-2-Clause +License: GPLv2 and BSD-2-Clause. URL: https://github.com/ClusterLabs/pcs # tar for unpacking pyagetx source tar ball @@ -294,11 +303,11 @@ update_times_patch(){ update_times ${patch_file_name} `diffstat -p1 -l ${patch_file_name}` } -# update_times_patch %%{PATCH1} update_times_patch %{PATCH1} +update_times_patch %{PATCH2} update_times_patch %{PATCH101} -cp -f %SOURCE1 pcsd/public/images +cp -f %SOURCE1 %{pcsd_public_dir}/images # prepare dirs/files necessary for building web ui # inside SOURCE100 is only directory %%{ui_src_name} tar -xzf %SOURCE100 -C %{pcsd_public_dir} @@ -306,94 +315,53 @@ tar -xf %SOURCE101 -C %{pcsd_public_dir}/%{ui_src_name} # prepare dirs/files necessary for building all bundles # ----------------------------------------------------- -# 1) configuration for rubygems -mkdir -p pcsd/.bundle -cp -f %SOURCE2 pcsd/.bundle/config +# 1) rubygems sources -# 2) rubygems sources -mkdir -p pcsd/vendor/cache -cp -f %SOURCE81 pcsd/vendor/cache -cp -f %SOURCE82 pcsd/vendor/cache -cp -f %SOURCE83 pcsd/vendor/cache -cp -f %SOURCE84 pcsd/vendor/cache -cp -f %SOURCE86 pcsd/vendor/cache +mkdir -p %{rubygem_cache_dir} +cp -f %SOURCE81 %{rubygem_cache_dir} +cp -f %SOURCE82 %{rubygem_cache_dir} +cp -f %SOURCE83 %{rubygem_cache_dir} +cp -f %SOURCE84 %{rubygem_cache_dir} +cp -f %SOURCE85 %{rubygem_cache_dir} +cp -f %SOURCE86 %{rubygem_cache_dir} # For reason why we are renaming open4 rubygem, see comment of source # definition above. -cp -f %SOURCE87 pcsd/vendor/cache/open4-%{version_rubygem_open4}.gem -cp -f %SOURCE88 pcsd/vendor/cache -cp -f %SOURCE89 pcsd/vendor/cache -cp -f %SOURCE90 pcsd/vendor/cache -cp -f %SOURCE91 pcsd/vendor/cache -cp -f %SOURCE92 pcsd/vendor/cache -cp -f %SOURCE93 pcsd/vendor/cache -cp -f %SOURCE94 pcsd/vendor/cache -cp -f %SOURCE95 pcsd/vendor/cache -cp -f %SOURCE96 pcsd/vendor/cache -cp -f %SOURCE97 pcsd/vendor/cache -cp -f %SOURCE98 pcsd/vendor/cache +cp -f %SOURCE87 %{rubygem_cache_dir}/open4-%{version_rubygem_open4}.gem +cp -f %SOURCE88 %{rubygem_cache_dir} +cp -f %SOURCE89 %{rubygem_cache_dir} +cp -f %SOURCE90 %{rubygem_cache_dir} +cp -f %SOURCE91 %{rubygem_cache_dir} +cp -f %SOURCE92 %{rubygem_cache_dir} +cp -f %SOURCE93 %{rubygem_cache_dir} +cp -f %SOURCE94 %{rubygem_cache_dir} +cp -f %SOURCE95 %{rubygem_cache_dir} +cp -f %SOURCE96 %{rubygem_cache_dir} +cp -f %SOURCE97 %{rubygem_cache_dir} -# 3) dir for python bundles -mkdir -p %{bundled_src_dir} - -# 4) sources for pyagentx -tar -xzf %SOURCE41 -C %{bundled_src_dir} -mv %{bundled_src_dir}/pyagentx-%{pyagentx_version} %{bundled_src_dir}/pyagentx -update_times %SOURCE41 `find %{bundled_src_dir}/pyagentx -follow` -cp %{bundled_src_dir}/pyagentx/LICENSE.txt pyagentx_LICENSE.txt -cp %{bundled_src_dir}/pyagentx/CONTRIBUTORS.txt pyagentx_CONTRIBUTORS.txt -cp %{bundled_src_dir}/pyagentx/README.md pyagentx_README.md - -# 5) sources for tornado -tar -xzf %SOURCE42 -C %{bundled_src_dir} -mv %{bundled_src_dir}/tornado-%{tornado_version} %{bundled_src_dir}/tornado -update_times %SOURCE42 `find %{bundled_src_dir}/tornado -follow` -cp %{bundled_src_dir}/tornado/LICENSE tornado_LICENSE -cp %{bundled_src_dir}/tornado/README.rst tornado_README.rst - -# 7) sources for python dacite -tar -xzf %SOURCE44 -C %{bundled_src_dir} -mv %{bundled_src_dir}/dacite-%{dacite_version} %{bundled_src_dir}/dacite -update_times %SOURCE44 `find %{bundled_src_dir}/dacite -follow` -cp %{bundled_src_dir}/dacite/LICENSE dacite_LICENSE -cp %{bundled_src_dir}/dacite/README.md dacite_README.md +# 2) prepare python bundles +mkdir -p %{pcs_bundled_dir}/src +cp -f %SOURCE41 rpm/ +cp -f %SOURCE42 rpm/ +cp -f %SOURCE44 rpm/ %build %define debug_package %{nil} +./autogen.sh +%{configure} --enable-local-build --enable-use-local-cache-only PYTHON=%{__python3} +make all + %install rm -rf $RPM_BUILD_ROOT pwd -# build bundled rubygems (in main install it is disabled by BUILD_GEMS=false) -mkdir -p %{rubygem_bundle_dir} -# The '-g' cflags option is needed for generation of MiniDebugInfo for shared -# libraries from rubygem extensions -# Currently used rubygems with extensions: eventmachine, ffi, json, thin -# There was rpmdiff issue with missing .gnu_debugdata section -# see https://docs.engineering.redhat.com/display/HTD/rpmdiff-elf-stripping -gem install \ - --force --verbose --no-document -l --no-user-install \ - -i %{rubygem_bundle_dir} \ - %{rubygem_cache_dir}/backports-%{version_rubygem_backports}.gem \ - %{rubygem_cache_dir}/daemons-%{version_rubygem_daemons}.gem \ - %{rubygem_cache_dir}/ethon-%{version_rubygem_ethon}.gem \ - %{rubygem_cache_dir}/eventmachine-%{version_rubygem_eventmachine}.gem \ - %{rubygem_cache_dir}/ffi-%{version_rubygem_ffi}.gem \ - %{rubygem_cache_dir}/json-%{version_rubygem_json}.gem \ - %{rubygem_cache_dir}/mustermann-%{version_rubygem_mustermann}.gem \ - %{rubygem_cache_dir}/open4-%{version_rubygem_open4}.gem \ - %{rubygem_cache_dir}/rack-protection-%{version_rubygem_rack_protection}.gem \ - %{rubygem_cache_dir}/rack-test-%{version_rubygem_rack_test}.gem \ - %{rubygem_cache_dir}/rack-%{version_rubygem_rack}.gem \ - %{rubygem_cache_dir}/rexml-%{version_rubygem_rexml}.gem \ - %{rubygem_cache_dir}/ruby2_keywords-%{version_rubygem_ruby2_keywords}.gem \ - %{rubygem_cache_dir}/sinatra-%{version_rubygem_sinatra}.gem \ - %{rubygem_cache_dir}/thin-%{version_rubygem_thin}.gem \ - %{rubygem_cache_dir}/tilt-%{version_rubygem_tilt}.gem \ - %{rubygem_cache_dir}/webrick-%{version_rubygem_webrick}.gem \ - -- '--with-ldflags=%{build_ldflags}' \ - '--with-cflags=%{optflags}' +%make_install + +# build web ui and put it to pcsd +make -C %{pcsd_public_dir}/%{ui_src_name} build +mv %{pcsd_public_dir}/%{ui_src_name}/build ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui +rm -r %{pcsd_public_dir}/%{ui_src_name} # prepare license files # some rubygems do not have a license file (ruby2_keywords, thin) @@ -416,33 +384,19 @@ mv %{rubygem_bundle_dir}/gems/sinatra-%{version_rubygem_sinatra}/LICENSE sinatra mv %{rubygem_bundle_dir}/gems/tilt-%{version_rubygem_tilt}/COPYING tilt_COPYING mv %{rubygem_bundle_dir}/gems/webrick-%{version_rubygem_webrick}/LICENSE.txt webrick_LICENSE.txt -# build web ui and put it to pcsd -make -C %{pcsd_public_dir}/%{ui_src_name} build -mv %{pcsd_public_dir}/%{ui_src_name}/build pcsd/public/ui -rm -r %{pcsd_public_dir}/%{ui_src_name} - -# main pcs install -%make_install \ - PREFIX=%{_prefix} \ - SYSTEMD_UNIT_DIR=%{_unitdir} \ - LIB_DIR=%{pcs_libdir} \ - PYTHON=%{__python3} \ - PYTHON_SITELIB=%{python3_sitelib} \ - BASH_COMPLETION_DIR=%{_datadir}/bash-completion/completions \ - BUNDLE_PYAGENTX_SRC_DIR=`readlink -f %{bundled_src_dir}/pyagentx` \ - BUNDLE_TORNADO_SRC_DIR=`readlink -f %{bundled_src_dir}/tornado` \ - BUNDLE_DACITE_SRC_DIR=`readlink -f %{bundled_src_dir}/dacite` \ - BUILD_GEMS=false \ - SYSTEMCTL_OVERRIDE=true \ - hdrdir="%{_includedir}" \ - rubyhdrdir="%{_includedir}" \ - includedir="%{_includedir}" - # symlink favicon into pcsd directories -ln -fs /etc/favicon.png ${RPM_BUILD_ROOT}%{pcs_libdir}/%{pcsd_public_dir}/images/favicon.png +ln -fs /etc/favicon.png ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/images/favicon.png -#after the ruby gem compilation we do not need ruby gems in the cache -rm -r -v $RPM_BUILD_ROOT%{pcs_libdir}/%{rubygem_cache_dir} + +cp %{pcs_bundled_dir}/src/pyagentx-*/LICENSE.txt pyagentx_LICENSE.txt +cp %{pcs_bundled_dir}/src/pyagentx-*/CONTRIBUTORS.txt pyagentx_CONTRIBUTORS.txt +cp %{pcs_bundled_dir}/src/pyagentx-*/README.md pyagentx_README.md + +cp %{pcs_bundled_dir}/src/tornado-*/LICENSE tornado_LICENSE +cp %{pcs_bundled_dir}/src/tornado-*/README.rst tornado_README.rst + +cp %{pcs_bundled_dir}/src/dacite-*/LICENSE dacite_LICENSE +cp %{pcs_bundled_dir}/src/dacite-*/README.md dacite_README.md # We are not building debug package for pcs but we need to add MiniDebuginfo # to the bundled shared libraries from rubygem extensions in order to satisfy @@ -452,14 +406,15 @@ rm -r -v $RPM_BUILD_ROOT%{pcs_libdir}/%{rubygem_cache_dir} /usr/lib/rpm/find-debuginfo.sh -j2 -m -i -S debugsourcefiles.list # find-debuginfo.sh generated some files into /usr/lib/debug and # /usr/src/debug/ that we don't want in the package -rm -rf $RPM_BUILD_ROOT%{pcs_libdir}/debug +rm -rf $RPM_BUILD_ROOT%{_libdir}/debug +rm -rf $RPM_BUILD_ROOT/usr/lib/debug rm -rf $RPM_BUILD_ROOT%{_prefix}/src/debug # We can remove files required for gem compilation -rm -rf $RPM_BUILD_ROOT%{pcs_libdir}/%{rubygem_bundle_dir}/gems/eventmachine-%{version_rubygem_eventmachine}/ext -rm -rf $RPM_BUILD_ROOT%{pcs_libdir}/%{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/ext -rm -rf $RPM_BUILD_ROOT%{pcs_libdir}/%{rubygem_bundle_dir}/gems/json-%{version_rubygem_json}/ext -rm -rf $RPM_BUILD_ROOT%{pcs_libdir}/%{rubygem_bundle_dir}/gems/thin-%{version_rubygem_thin}/ext +rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/eventmachine-%{version_rubygem_eventmachine}/ext +rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/ext +rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/json-%{version_rubygem_json}/ext +rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/thin-%{version_rubygem_thin}/ext %check # In the building environment LC_CTYPE is set to C which causes tests to fail @@ -482,8 +437,7 @@ run_all_tests(){ # passing outside the mock environment. # TODO: Investigate the issue - BUNDLED_LIB_LOCATION=$RPM_BUILD_ROOT%{pcs_libdir}/pcs/bundled/packages \ - %{__python3} pcs_test/suite.py --tier0 -v --vanilla --all-but \ + %{__python3} pcs_test/suite --tier0 -v --vanilla --all-but \ pcs_test.tier0.lib.commands.test_resource_agent.DescribeAgentUtf8.test_describe \ pcs_test.tier0.daemon.app.test_app_remote.SyncConfigMutualExclusive.test_get_not_locked \ pcs_test.tier0.daemon.app.test_app_remote.SyncConfigMutualExclusive.test_post_not_locked \ @@ -491,11 +445,10 @@ run_all_tests(){ test_result_python=$? #run pcsd tests and remove them - pcsd_dir=$RPM_BUILD_ROOT%{pcs_libdir}/pcsd - GEM_HOME=$RPM_BUILD_ROOT%{pcs_libdir}/%{rubygem_bundle_dir} ruby \ - -I${pcsd_dir} \ - -I${pcsd_dir}/test \ - ${pcsd_dir}/test/test_all_suite.rb + GEM_HOME=$RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir} ruby \ + -I$RPM_BUILD_ROOT%{_libdir}/pcsd \ + -Ipcsd/test \ + pcsd/test/test_all_suite.rb test_result_ruby=$? if [ $test_result_python -ne 0 ]; then @@ -505,12 +458,8 @@ run_all_tests(){ } remove_all_tests() { - pcsd_dir=$RPM_BUILD_ROOT%{pcs_libdir}/pcsd - #remove pcsd tests, we do not distribute them in the rpm - rm -r -v ${pcsd_dir}/test - # remove javascript testing files - rm -r -v ${pcsd_dir}/public/js/dev + rm -r -v $RPM_BUILD_ROOT%{_libdir}/%{pcsd_public_dir}/js/dev } run_all_tests @@ -572,15 +521,11 @@ remove_all_tests %license sinatra_LICENSE %license tilt_COPYING %license webrick_LICENSE.txt -%{python3_sitelib}/pcs -%{python3_sitelib}/pcs-%{version}-py3.*.egg-info +%{python3_sitelib}/* %{_sbindir}/pcs %{_sbindir}/pcsd -%{pcs_libdir}/pcs/pcs_internal -%{pcs_libdir}/pcsd/* -%{pcs_libdir}/pcsd/.bundle/config -%{pcs_libdir}/pcs/bundled/packages/tornado* -%{pcs_libdir}/pcs/bundled/packages/dacite* +%{_libdir}/pcs/* +%{_libdir}/pcsd/* %{_unitdir}/pcsd.service %{_unitdir}/pcsd-ruby.service %{_datadir}/bash-completion/completions/pcs @@ -598,22 +543,13 @@ remove_all_tests %ghost %config(noreplace) %attr(0644,root,root) %{_sharedstatedir}/pcsd/pcs_users.conf %{_mandir}/man8/pcs.* %{_mandir}/man8/pcsd.* -%exclude %{pcs_libdir}/pcsd/*.debian -%exclude %{pcs_libdir}/pcsd/pcsd.service -%exclude %{pcs_libdir}/pcsd/pcsd-ruby.service -%exclude %{pcs_libdir}/pcsd/pcsd.conf -%exclude %{pcs_libdir}/pcsd/pcsd.8 -%exclude %{pcs_libdir}/pcsd/public/js/dev/* -%exclude %{pcs_libdir}/pcsd/Gemfile -%exclude %{pcs_libdir}/pcsd/Gemfile.lock -%exclude %{pcs_libdir}/pcsd/Makefile -%exclude %{python3_sitelib}/pcs/bash_completion -%exclude %{python3_sitelib}/pcs/pcs.8 -%exclude %{python3_sitelib}/pcs/pcs +%exclude %{_libdir}/pcs/pcs_snmp_agent +%exclude %{_libdir}/pcs/%{pcs_bundled_dir}/packages/pyagentx* + %files -n %{pcs_snmp_pkg_name} -%{pcs_libdir}/pcs/pcs_snmp_agent -%{pcs_libdir}/pcs/bundled/packages/pyagentx* +%{_libdir}/pcs/pcs_snmp_agent +%{_libdir}/pcs/%{pcs_bundled_dir}/packages/pyagentx* %{_unitdir}/pcs_snmp_agent.service %{_datadir}/snmp/mibs/PCMK-PCS*-MIB.txt %{_mandir}/man8/pcs_snmp_agent.* @@ -625,6 +561,11 @@ remove_all_tests %license pyagentx_LICENSE.txt %changelog +* Thu Jun 10 2021 Miroslava Lisik - 0.10.8-6 +- Rebased to latest upstream sources (see CHANGELOG.md) +- Removed clufter related commands +- Resolves: rhbz#1881064 + * Wed Apr 28 2021 Miroslav Lisik - 0.10.8-5 - Updated pcs web ui node modules - Fixed build issue on low memory build hosts diff --git a/sources b/sources index 5abf545..235f45a 100644 --- a/sources +++ b/sources @@ -1,7 +1,7 @@ SHA512 (pyagentx-0.4.pcs.2.tar.gz) = d4194fec9a3e5fefe3793d49b7fec1feafef294c7e613a06046c2993daeefc5cb39d7c5b2b402ff83e49b2d976953f862264288c758c0be09d997b5323cc558a SHA512 (open4-1.3.4-1.gem) = 838a18efcd093d55d9589ff9d5c11054618abef863224c2d9b31445dc735218c2f96d954040e2d3f8d5aab0140e54b627fcc4a1b01c17e59267402a2abdd8efb -SHA512 (pcsd-bundle-config-2) = f2a2df2dab39c2012cc6a91517716dde8f5a48788d1069c4addf619bc4dc45a98fd48f0f7964b5400e43e84fe96f942a550d2762553fea97e63dc7ad9b8be823 -SHA512 (pcs-web-ui-0.1.5.tar.gz) = ec4adf8ca5858c1f1f82e8f58e36864805bedc6dc10674fab83498aff5422a0497703ecd96fda17b4c1f6beffa64fe5a80a82fb4f75b2102fe1a4753a5d057e9 +SHA512 (pcs-web-ui-node-modules-0.1.6.tar.xz) = 30e9d2aa65e199e05a756ed01b549f33766cd28eaaeda40ed5218f791cbfdefc16bdcc6c9a309bddecf750c562de571634680ce39af3fb4e6045294061d789bf +SHA512 (pcs-web-ui-0.1.6.tar.gz) = d5361155e943330d489fbc69442777a0c45d6fec12894a6b2158e0ad583d2fd2307a13615d39a770352c4c37473919b5e13c8d13e84cd4b778ac719de51c6c20 SHA512 (daemons-1.3.1.gem) = eede065019b5e251e5b7d0959251c8591ec8c38ada6861a1c41cf85959666a4865efc69178f63bf2acfc1e993c8222d581ac5d689be439744ee3cef0ca6f5138 SHA512 (eventmachine-1.2.7.gem) = fdbcf9fc933e2414e70f8f48153e9ba6ed7a0029cdf49cdcb4ab72ab26683e727a36c099f017f20681f9c361179461743e501278ca9bd5612e693e26867cc516 SHA512 (thin-1.7.2.gem) = e9e0ad3dab77a1c6f3e413ce7ed1598da0db5fa62355a1fbbc73153d2fd810d82d5bf2e6a434429912eb885c263c674364a5dec7d878960e2dbef37ccbe1472b @@ -18,7 +18,6 @@ SHA512 (backports-3.17.2.gem) = e860e4c1784b49e81294ce0bdd27226e28bbec9163398d79 SHA512 (rack-2.2.3.gem) = aabda2ac4aeea6b119c5d570a6c36b5c114f879cc73678a6f385b71f2191501a86adc3bed6f0e0bacfc1e4c48c2374714588669ede898053dc7719899bf71635 SHA512 (tornado-6.1.0.tar.gz) = bd161a1c30f40f983d608297bca113735cb4baad255de71302a5b4d35be8c02afbc9820728efa912e62e1cbbfad8f92360261a69e0c8759f9e6cb477fbca31c7 SHA512 (dacite-1.6.0.tar.gz) = 034255f095589d309fe5805413d8b148f430cd20a0de305b7954083b530d516da1d8f3f00ebb5264a8cfb77f2b2a76f1e2d863e78bd191f1d85021c5553815da -SHA512 (pcs-0.10.8.tar.gz) = 8b9ba62279431e481d062e804d24480d2a274d2f4897a82149df6116ff3df2394d97a3ee77a6dee4c563d915bab0142124a8942524fcc4e894912086e865353c -SHA512 (rexml-3.2.4.gem) = 05cd28b4b4477c306a07e9eccbc226aabea0a8e5497e04ce55a6f4407cd278acdba754561265dc6f57c48d09e0a1d91e757e7bfaba67fd59bbf4d8eecdaa3459 SHA512 (webrick-1.7.0.gem) = 5f242b50300046fe7c22ecd1640a73e5815e05a72bedfebe6bc39c24c92bd61abdd180860de0d194c0eebbc640b507b6892de181d3b577c5372ace0ca6faf2a3 -SHA512 (pcs-web-ui-node-modules-0.1.5.fix.1.tar.xz) = 3e529dbd58f563847da3e62f47da02b57225aa98f35b55dc7c67e64512a20832c174ee3258f1aaa621cf7d8ed60936bf4b40d9b81c530bdf21a1b4e92687421a +SHA512 (rexml-3.2.5.gem) = 1e3838d4a5befa76137fb8fea6a20195490645aa2b1c5d14d1eeca6c093d7f64eb405f07fd07b00fcafa9606dc78f9f0a488012338f81414623feb6e8cb83931 +SHA512 (pcs-0.10.8.181-47e9.tar.gz) = 8a2e6109690f74363d964ba5a046d56b3c99e21e119bccfdf926e27db7be196e90e699ad8c7a80c3eba26e6fef91c8048c4afc7b10657cb1ef30731e88ba3f72 diff --git a/tests/tests.yml b/tests/tests.yml index af0addd..b9aea8a 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -18,7 +18,7 @@ - name: Start pcsd systemd: state: started - name: pcsd.service + name: pcsd daemon_reload: yes roles: @@ -30,6 +30,7 @@ - automake - make - rpm-build + - ruby-devel - git-core - booth-site - fence-agents-apc @@ -39,8 +40,12 @@ - openssl - pcs - pcs-snmp + - python3-setuptools_scm + - python3-wheel + - rubygem-test-unit + - wget required_services: - - pcsd.service + - pcsd tests: # dir: . -> dot means tests dir in distgit - prepare-source: @@ -49,15 +54,18 @@ - flatten-source: dir: ./ run: shopt -s dotglob; mv {{tenv_workdir}}/source/*/* {{tenv_workdir}}/source + - build_sources: + dir: ./source + run: "export PYTHONPATH=/usr/lib64/pcs/pcs_bundled/packages/; export GEM_HOME=/usr/lib64/pcsd/vendor/bundle/; ./autogen.sh && ./configure" - remove_sources: dir: ./source run: rm -rfv pcs - run_upstream_tier0_tests: dir: ./source - run: pcs_test/suite.py --tier0 -v --vanilla --installed + run: pcs_test/suite --tier0 -v --vanilla --installed - run_upstream_tier1_tests: dir: ./source - run: pcs_test/suite.py --tier1 -v --vanilla --installed + run: pcs_test/suite --tier1 -v --vanilla --installed - run_smoke_tests: dir: ./source run: pcs_test/smoke.sh