Name:    pcs
Version: 0.11.7
Release: 9
License: GPL-2.0-only AND Apache-2.0 AND MIT AND BSD-3-Clause AND (BSD-2-Clause OR Ruby) AND (BSD-2-Clause OR GPL-2.0-or-later)
URL:     https://github.com/ClusterLabs/pcs
Group: System Environment/Base
Summary: Pacemaker Configuration System

%global version_or_commit %{version}
%global pcs_source_name %{name}-%{version_or_commit}

# ui_commit can be determined by hash, tag or branch
%global ui_commit 0.1.18
%global ui_modules_version 0.1.18
%global ui_src_name pcs-web-ui-%{ui_commit}

%global pcs_snmp_pkg_name  pcs-snmp

%global pyagentx_version  0.4.pcs.2
%global dacite_version 1.8.1

%global required_pacemaker_version 2.1.0

%global pcs_bundled_dir pcs_bundled
%global pcsd_public_dir pcsd/public
%global rubygem_bundle_dir pcsd/vendor/bundle
%global rubygem_cache_dir %{rubygem_bundle_dir}/cache

#part after last slash is recognized as filename in look-aside repository
#desired name is achived by trick with hash anchor
Source0: %{url}/archive/%{?v_prefix}%{version_or_commit}/%{pcs_source_name}.tar.gz
Source1: https://github.com/ondrejmular/pyagentx/archive/v%{pyagentx_version}/pyagentx-%{pyagentx_version}.tar.gz
Source2: https://github.com/konradhalas/dacite/archive/v%{dacite_version}/dacite-%{dacite_version}.tar.gz
Source3: https://github.com/ClusterLabs/pcs-web-ui/archive/%{ui_commit}/%{ui_src_name}.tar.gz
Source4: https://github.com/ClusterLabs/pcs-web-ui/releases/download/%{ui_commit}/pcs-web-ui-node-modules-%{ui_modules_version}.tar.xz

# pcs patches: <= 200
# Patch0: bzNUMBER-01-name.patch
Patch0: do-not-support-cluster-setup-with-udp-u-transport.patch
Patch1: Support-for-openEuler.patch
Patch2: fix-do-not-put-empty-uid-gid-options-to-an-uidgid-fi.patch
Patch3: fix-stonith-level-validation.patch
Patch4: Fix-pcsd-ruby.patch
Patch5: update-crm_mon-schemas-for-tests.patch
Patch6: add-dtos-and-converting-functions-for-resources-stat.patch
Patch7: fixes-after-review.patch
Patch8: store-clone-instance-id-in-resource-status-dtos.patch

# ui patches: >200
# Patch201: bzNUMBER-01-name.patch

# git for patches
BuildRequires: git-core
BuildRequires: make
# printf from coreutils is used in makefile, head is used in spec
BuildRequires: coreutils
# python for pcs
BuildRequires: python3 >= 3.9
BuildRequires: python3-dateutil >= 2.7.0
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-pycurl
BuildRequires: python3-pip
BuildRequires: python3-pyparsing
BuildRequires: python3-tornado
BuildRequires: python3-cryptography
BuildRequires: python3-lxml
# for building bundled python packages
BuildRequires: python3-wheel
# for bundled python dateutil
# dateutil was unbundled in Fedora but our autotools still check for it
BuildRequires: python3-setuptools_scm
# gcc for compiling custom rubygems
BuildRequires: gcc
BuildRequires: gcc-c++
# ruby and gems for pcsd
BuildRequires: ruby >= 2.5.0
BuildRequires: ruby-devel
BuildRequires: rubygems
BuildRequires: rubygem-bundler
BuildRequires: rubygem-backports
BuildRequires: rubygem-childprocess
BuildRequires: rubygem-ethon
BuildRequires: rubygem-ffi
BuildRequires: rubygem-json
BuildRequires: rubygem-mustermann
BuildRequires: rubygem-puma
BuildRequires: rubygem-rack
BuildRequires: rubygem-rack-protection
BuildRequires: rubygem-rack-test
BuildRequires: rubygem-sinatra
BuildRequires: rubygem-tilt
BuildRequires: rubygem(rexml)
# ruby libraries for tests
BuildRequires: rubygem-test-unit

# for touching patch files (sanitization function)
BuildRequires: diffstat
# for post, preun and postun macros
BuildRequires: systemd
# pam is used for authentication inside daemon (python ctypes)
# needed for tier0 tests during build
BuildRequires: pam
BuildRequires: make
# for working with qdevice certificates (certutil) - used in configure.ac
BuildRequires: nss-tools

# 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 >= %{required_pacemaker_version}
BuildRequires: resource-agents
BuildRequires: sbd

# python and libraries for pcs, setuptools for pcs entrypoint
Requires: python3 >= 3.9
Requires: python3-cryptography
Requires: python3-dateutil >= 2.7.0
Requires: python3-lxml
Requires: python3-setuptools
Requires: python3-pycurl
Requires: python3-pyparsing
Requires: python3-tornado
# ruby and gems for pcsd
Requires: ruby >= 2.5.0
Requires: rubygem-backports
Requires: rubygem-childprocess
Requires: rubygem-ethon
Requires: rubygem-ffi
Requires: rubygem-json
Requires: rubygem-mustermann
Requires: rubygem-puma
Requires: rubygem-rack
Requires: rubygem-rack-protection
Requires: rubygem-rack-test
Requires: rubygem-sinatra
Requires: rubygem-tilt
Requires: rubygem(rexml)
# for killall
Requires: psmisc
# cluster stack and related packages
Requires: pcmk-cluster-manager >= %{required_pacemaker_version}
Suggests: pacemaker
Requires: (corosync >= 3.0 if pacemaker)
# pcs enables corosync encryption by default so we require libknet1-plugins-all
Requires: (libknet1-plugins-all if corosync)
Requires: pacemaker-cli >= %{required_pacemaker_version}
# for post, preun and postun macros
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
# pam is used for authentication inside daemon (python ctypes)
# more details: https://bugzilla.redhat.com/show_bug.cgi?id=1717113
Requires: pam
# needs logrotate for /etc/logrotate.d/pcsd
Requires: logrotate
# for working with qdevice certificates (certutil)
Requires: nss-tools

Provides: bundled(dacite) = %{dacite_version}

%description
pcs is a corosync and pacemaker configuration tool.  It permits users to
easily view, modify and create pacemaker based clusters.

# pcs-snmp package definition
%package -n %{pcs_snmp_pkg_name}
Summary: Pacemaker cluster SNMP agent
License: GPL-2.0-only and BSD-2-Clause

# tar for unpacking pyagetx source tarball
BuildRequires: tar

Requires: pcs = %{version}-%{release}
Requires: pacemaker
Requires: net-snmp

Provides: bundled(pyagentx) = %{pyagentx_version}

%description -n %{pcs_snmp_pkg_name}
SNMP agent that provides information about pacemaker cluster to the master agent (snmpd)

%prep

# -- following is inspired by python-simplejon.el5 --
# Update timestamps on the files touched by a patch, to avoid non-equal
# .pyc/.pyo files across the multilib peers within a build

update_times(){
  # update_times <reference_file> <file_to_touch> ...
  # set the access and modification times of each file_to_touch to the times
  # of reference_file

  # put all args to file_list
  file_list=("$@")
  # first argument is reference_file: so take it and remove from file_list
  reference_file=${file_list[0]}
  unset file_list[0]

  for fname in ${file_list[@]}; do
    # some files could be deleted by a patch therefore we test file for
    # existance before touch to avoid exit with error: No such file or
    # directory
    # diffstat cannot create list of files without deleted files
    test -e $fname && touch -r $reference_file $fname
  done
}

update_times_patch(){
  # update_times_patch <patch_file_name>
  # set the access and modification times of each file in patch to the times
  # of patch_file_name

  patch_file_name=$1

  # diffstat
  # -l lists only the filenames. No histogram is generated.
  # -p override the logic that strips common pathnames,
  #    simulating the patch "-p" option. (Strip the smallest prefix containing
  #    num leading slashes from each file name found in the patch file)
  update_times ${patch_file_name} `diffstat -p1 -l ${patch_file_name}`
}

# documentation for setup/autosetup/autopatch:
#   * http://ftp.rpm.org/max-rpm/s1-rpm-inside-macros.html
#   * https://rpm-software-management.github.io/rpm/manual/autosetup.html
# patch web-ui sources
%autosetup -D -T -b 3 -a 4 -S git -n %{ui_src_name} -N
%autopatch -p1 -m 201
# update_times_patch %%{PATCH201}

# patch pcs sources
%autosetup -S git -n %{pcs_source_name} -N
%autopatch -p1 -m 0
# update_times_patch %%{PATCH0}
update_times_patch %{PATCH0}
sed -i "s/setuptools-scm/setuptools_scm/g" configure.ac

# generate .tarball-version if building from an untagged commit, not a released version
# autogen uses git-version-gen which uses .tarball-version for generating version number
%if "%{version}" != "%{version_or_commit}"
  echo "%version+$(echo "%{version_or_commit}" | head -c 8)" > %{_builddir}/%{pcs_source_name}/.tarball-version
%endif

# prepare dirs/files necessary for building python bundles
mkdir -p %{pcs_bundled_dir}/src
cp -f %SOURCE1 rpm/
cp -f %SOURCE2 rpm/

%build
%define debug_package %{nil}

./autogen.sh
%{configure} --enable-local-build --enable-use-local-cache-only --enable-individual-bundling PYTHON=%{__python3} ruby_CFLAGS="%{optflags}" ruby_LIBS="%{build_ldflags}"
make all

# build pcs-web-ui
BUILD_USE_CURRENT_NODE_MODULES=true make -C %{_builddir}/%{ui_src_name} build

%install
rm -rf $RPM_BUILD_ROOT
pwd

%make_install

# install pcs-web-ui
cp -r %{_builddir}/%{ui_src_name}/build  ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui

# symlink favicon into pcsd directories
mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui/static/media
ln -fs /etc/favicon.png ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui/static/media/favicon.png

# prepare license files
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/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
# rpmdiff's binary stripping checker.
# Therefore we call find-debuginfo from debugedit manually in order to strip
# binaries and add MiniDebugInfo with .gnu_debugdata section
find-debuginfo -j2 -m -i -S debugsourcefiles.list
# find-debuginfo generated some files into /usr/lib/debug  and
# /usr/src/debug/ that we don't want in the package
rm -rf $RPM_BUILD_ROOT%{_libdir}/debug
rm -rf $RPM_BUILD_ROOT/usr/lib/debug
rm -rf $RPM_BUILD_ROOT%{_prefix}/src/debug

%check
# In the building environment LC_CTYPE is set to C which causes tests to fail
# due to python prints a warning about it to stderr. The following environment
# variable disables the warning.
# On the live system either UTF8 locale is set or the warning is emmited
# which breaks pcs. That is the correct behavior since with wrong locales it
# would be probably broken anyway.
# The main concern here is to make the tests pass.
# See https://fedoraproject.org/wiki/Changes/python3_c.utf-8_locale for details.
export PYTHONCOERCECLOCALE=0

run_all_tests(){
  #run pcs tests

  # disabled tests:
  #
  %{__python3} pcs_test/suite --tier0 -v --vanilla --all-but \
  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 \

  test_result_python=$?

  #run pcsd tests and remove them
  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
    return $test_result_python
  fi
  return $test_result_ruby
}

run_all_tests

%posttrans
# Make sure the new version of the daemon is running.
# Also, make sure to start pcsd-ruby if it hasn't been started or even
# installed before. This is done by restarting pcsd.service.
%{_bindir}/systemctl daemon-reload
%{_bindir}/systemctl try-restart pcsd.service

%post
%systemd_post pcsd.service
%systemd_post pcsd-ruby.service

%post -n %{pcs_snmp_pkg_name}
%systemd_post pcs_snmp_agent.service

%preun
%systemd_preun pcsd.service
%systemd_preun pcsd-ruby.service

%preun -n %{pcs_snmp_pkg_name}
%systemd_preun pcs_snmp_agent.service

%postun
%systemd_postun_with_restart pcsd.service
%systemd_postun_with_restart pcsd-ruby.service

%postun -n %{pcs_snmp_pkg_name}
%systemd_postun_with_restart pcs_snmp_agent.service

%files
%doc CHANGELOG.md
%doc README.md
%doc dacite_README.md
%license dacite_LICENSE
%license COPYING
%{python3_sitelib}/*
%{_sbindir}/pcs
%{_sbindir}/pcsd
%{_libdir}/pcs/*
%{_libdir}/pcsd/*
%{_unitdir}/pcsd.service
%{_unitdir}/pcsd-ruby.service
%{_datadir}/bash-completion/completions/pcs
%{_sharedstatedir}/pcsd
%config(noreplace) %{_sysconfdir}/pam.d/pcsd
%dir %{_var}/log/pcsd
%config(noreplace) %{_sysconfdir}/logrotate.d/pcsd
%config(noreplace) %{_sysconfdir}/sysconfig/pcsd
%ghost %config(noreplace) %attr(0600,root,root) %{_sharedstatedir}/pcsd/cfgsync_ctl
%ghost %config(noreplace) %attr(0600,root,root) %{_sharedstatedir}/pcsd/known-hosts
%ghost %config(noreplace) %attr(0600,root,root) %{_sharedstatedir}/pcsd/pcsd.cookiesecret
%ghost %config(noreplace) %attr(0600,root,root) %{_sharedstatedir}/pcsd/pcsd.crt
%ghost %config(noreplace) %attr(0600,root,root) %{_sharedstatedir}/pcsd/pcsd.key
%ghost %config(noreplace) %attr(0644,root,root) %{_sharedstatedir}/pcsd/pcs_settings.conf
%ghost %config(noreplace) %attr(0644,root,root) %{_sharedstatedir}/pcsd/pcs_users.conf
%{_mandir}/man8/pcs.*
%{_mandir}/man8/pcsd.*
%exclude %{_libdir}/pcs/pcs_snmp_agent
%exclude %{_libdir}/pcs/%{pcs_bundled_dir}/packages/pyagentx*


%files -n %{pcs_snmp_pkg_name}
%{_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.*
%config(noreplace) %{_sysconfdir}/sysconfig/pcs_snmp_agent
%doc CHANGELOG.md
%doc pyagentx_CONTRIBUTORS.txt
%doc pyagentx_README.md
%license COPYING
%license pyagentx_LICENSE.txt

%changelog
* Tue Mar 26 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-9
- Add dtos for resources status

* Mon Mar 25 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-8
- fixes after review

* Fri Mar 22 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-7
- add dtos and converting functions for resources status

* Tue Mar 19 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-6
- update crm_mon schemas for tests

* Tue Mar 19 2024 panchenbo <panchenbo@kylinsec.com.cn> - 0.11.7-5
- fix setuptools_scm not found

* Tue Mar 12 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-4
- Fix pcsd ruby

* Mon Mar 04 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-3
- fix stonith level validation

* Fri Mar 01 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-2
- fixed command `pcs cluster uidgid add`

* Tue Feb 27 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-1
- Update package to version 0.11.7

* Thu Nov 23 2023 bixiaoyan <bixiaoyan@kylinos.cn> - 0.11.2-10
- Fix serving static files

* Wed Oct 25 2023 zouzhimin <zouzhimin@kylinos.cn> - 0.11.2-9
- improve error messages in pcs resource move

* Fri Oct 20 2023 bizhiyuan <bizhiyuan@kylinos.cn> - 0.11.2-8
- Fix-CVE-2022-2735

* Thu Oct 19 2023 bizhiyuan <bizhiyuan@kylinos.cn> - 0.11.2-7
- Fix CVE-2022-1049

* Wed Sep 06 2023 bizhiyuan <bizhiyuan@kylinos.cn> - 0.11.2-6
- fix datetime race condition

* Tue Sep 05 2023 zouzhimin <zouzhimin@kylinos.cn> - 0.11.2-5
- Fix pcs quorum device remove

* Thu Aug 31 2023 bizhiyuan <bizhiyuan@kylinos.cn> - 0.11.2-4
- Fix pcs config checkpoint diff command

* Wed Aug 23 2023 jiangxinyu <jiangxinyu@kylinos.cn> - 0.11.2-3
- Fix typing in resource_agent package

* Mon Aug 07 2023 bizhiyuan <bizhiyuan@kylinos.cn> - 0.11.2-2
- Adjust regex pattern for ruby to support json 2.6.3 build error

* Mon Feb 06 2023 jiangxinyu <jiangxinyu@kylinos.cn> - 0.11.2-1
- Update package to version 0.11.2

* Wed Sep 07 2022 jiangxinyu <jiangxinyu@kylinos.cn> - 0.10.8-4
- Type:cves
- ID:CVE-2022-2735
- SUG:NA
- DESC:fix CVE-2022-2735

* Wed Jul 20 2022 wangqiang <wangqiang1@kylinos.cn> - 0.10.8-3
- Type:Feature
- ID:NA
- SUG:NA
- DESC:delete "-S git" from %autosetup

* Fri Jun 17 2022 duyiwei <duyiwei@kylinos.cn> - 0.10.8-2
- FIX-CVE-2022-1049

* Thu Mar 10 2022 jiangxinyu <jiangxinyu@kylinos.cn> - 0.10.8-1
- update to 0.10.8

* Fri Oct 30 2020 jiangxinyu <jiangxinyu@kylinos.cn> - 0.10.5-1
- Upgrade the pcs package version to 0.10.5-1

* Sun Apr 26 2020 wangmian<wangmian@kylinos.cn> - 0.10.2-5
- Change pcs ui

* Wed Apr 22 2020 houjian<houjian@kylinos.cn> - 0.10.2-4
- Init the project
