File ganeti.spec of Package ganeti

%define _local_libdir %_prefix/local/%{_lib}
%define os_search_path %{_datadir}/%{name}/os,%{_libdir}/%{name}/os,%{_local_libdir}/%{name}/os,/srv/%{name}/os,/srv/%{name}/shared-file-storage/os
%define iallocator_search_path %{_libdir}/%{name}/iallocators,%{_local_libdir}/%{name}/iallocators
%define extstorage_search_path %{_libdir}/%{name}/extstorage,%{_local_libdir}/%{name}/extstorage,/srv/%{name}/extstorage,/srv/%{name}/shared-file-storage/extstorage, %{_datadir}/%{name}/extstorage
%define GNT_USERGROUP_PREFIX gnt-

%define v_minor 3.1

Summary: Cluster-based virtualization management software
Name: ganeti
Version: %{v_minor}.0
Release: 0
License: BSD-2-Clause
URL: https://ganeti.org
# https://github.com/ganeti/ganeti/archive/refs/tags/v<version>.tar.gz
Source0: %{name}-%{version}.tar.gz
Patch0: bitarray3-compat.patch
Patch1: bitarray3-compat-stable31.patch
Patch2: pytest-legacy-invalid-escape-sequence.patch
Patch3: Make_RBD_user-id_configurable.patch 

# build system
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: make
BuildRequires: fdupes

# system tools
%systemd_requires
BuildRequires: socat
BuildRequires: man
BuildRequires: qemu-img
BuildRequires: graphviz
# PNG support
BuildRequires: graphviz-gd
# Helvetica fontconfig support
BuildRequires: graphviz-gnome
BuildRequires: iproute2
BuildRequires: fakeroot

# Python
BuildRequires: python3-base
BuildRequires: python3-bitarray
BuildRequires: python3-pyOpenSSL
BuildRequires: python3-pyparsing
%if 0%{?suse_version} >= 1600
BuildRequires: python3-pyasyncore
%endif
BuildRequires: python3-pyinotify
BuildRequires: python3-pycurl
BuildRequires: python3-PyYAML
BuildRequires: python3-psutil
BuildRequires: python3-docutils
BuildRequires: python3-Sphinx
# Python-Tests
BuildRequires: python3-coverage
# Python release skript
BuildRequires: python3-paramiko
# optional
BuildRequires: python3-pycodestyle
BuildRequires: python3-pylint

# Haskell tools
BuildRequires: cabal-install
BuildRequires: hscolour
BuildRequires: pandoc
%if 0%{?suse_version} >= 1600
BuildRequires: hlint
%endif
# Haskell + modules
BuildRequires: ghc
BuildRequires: ghc-curl-devel
BuildRequires: ghc-json-devel
BuildRequires: ghc-network-devel
BuildRequires: ghc-base64-bytestring-devel
BuildRequires: ghc-utf8-string-devel
BuildRequires: ghc-zlib-devel
BuildRequires: ghc-hslogger-devel
BuildRequires: ghc-attoparsec-devel
BuildRequires: ghc-vector-devel
BuildRequires: ghc-hinotify-devel
BuildRequires: ghc-cryptonite-devel
BuildRequires: ghc-lifted-base-devel
BuildRequires: ghc-lens-devel
BuildRequires: ghc-old-time-devel
BuildRequires: ghc-temporary-devel
BuildRequires: ghc-regex-tdfa-devel
BuildRequires: ghc-snap-server-devel
BuildRequires: ghc-PSQueue-devel
BuildRequires: ghc-QuickCheck-devel
BuildRequires: ghc-test-framework-hunit-devel
BuildRequires: ghc-test-framework-quickcheck2-devel

# GHC and modules not via RPM -> ghcup
# curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
# cabal v1-install HUnit QuickCheck attoparsec base64-bytestring case-insensitive cryptonite curl hinotify hslogger json lens lifted-base monad-control network old-time parallel random temporary test-framework test-framework-hunit test-framework-quickcheck2 transformers-base utf8-string zlib regex-tdfa pandoc alex happy snap-server PSQueue Cabal pandoc-cli

# or maybe 
# cabal v1-install --only-dependencies ganeti.cabal

# If you encounter this error
# Setup.hs:1:1: error:
#     Could not load module ‘Distribution.Simple’
#     It is a member of the hidden package ‘Cabal-3.10.3.0’.
#     You can run ‘:set -package Cabal’ to expose it.
# 
# add Cabal-3.10.3.0 to:
# cat ~/.ghc/x86_64-linux-9.6.7/environments/default
# clear-package-db
# global-package-db
# package-db /data/ghc/.cabal/store/ghc-9.6.7/package.db
# package-id base-4.18.3.0
# package-id Cabal-3.10.3.0

BuildRoot: %{_tmppath}/%{name}-root

# generel
Requires: lvm2
Requires: openssh-clients
Requires: openssh-server
Requires: iproute2
Requires: libcap-progs
Requires: openssl
Requires: socat
Requires: fping
Requires: qemu
Requires: man
Requires: libcurl4
Requires: hostname
# start-stop-daemon
Requires: dpkg

# Storage solutions
Suggests: qemu-block-rbd
Suggests: drbd-utils

# Python
Requires: python3-base
Requires: python3-bitarray
Requires: python3-simplejson
Requires: python3-pyparsing
%if 0%{?suse_version} >= 1600
Requires: python3-pyasyncore
%endif
Requires: python3-pyOpenSSL
Requires: python3-pyinotify
Requires: python3-pycurl
Requires: python3-psutil
#Requires: libnss_uidpool2

%description
Ganeti is a virtualization cluster management software. You are expected
to be a system administrator familiar with your Linux distribution and
the Xen or KVM virtualization environments before using it.

The various components of Ganeti all have man pages and interactive
help. This manual though will help you getting familiar with the system
by explaining the most common operations, grouped by related use.

After a terminology glossary and a section on the prerequisites needed
to use this manual, the rest of this document is divided in sections
for the different targets that a command affects: instance, nodes, etc.

%prep
%setup -q
%if 0%{?suse_version} >= 1600
# bitarray
%patch 0 -p1
%patch 1 -p1
# pytest
%patch 2 -p1
# RBD user
%patch 3 -p1
%else
# pytest
%patch2 -p1
# RBD user
%patch3 -p1
%endif

%build
if [[ -x ./autogen.sh ]]; then
	# build from git
	./autogen.sh
	echo "v%{version}" > vcs-version
else
	# build from release tarball
	autoreconf -i
fi

%configure \
  --prefix=%{_prefix} \
  --sysconfdir=%{_sysconfdir} \
  --libdir=%{_libdir} \
  --with-sshd-restart-command="/sbin/service sshd restart" \
  --with-export-dir=%{_localstatedir}/lib/%{name}/export \
  --with-os-search-path=%{os_search_path} \
  --with-iallocator-search-path=%{iallocator_search_path} \
  --with-extstorage-search-path=%{extstorage_search_path} \
  --with-kvm-path=/usr/bin/qemu-kvm \
  --with-disk-separator=_ \
  --with-kvm-kernel=/boot/vmlinuz \
  --enable-symlinks \
  --enable-restricted-commands \
  --enable-monitoring \
  --enable-metadata \
  --enable-restricted-commands \
  --with-user-prefix=%{GNT_USERGROUP_PREFIX} \
  --with-group-prefix=%{GNT_USERGROUP_PREFIX} \
  --enable-regex-tdfa
  
make

%install
export NO_BRP_STALE_LINK_ERROR=yes

make DESTDIR=${RPM_BUILD_ROOT} install

install -d -m 755 $RPM_BUILD_ROOT%{_unitdir}
install -m 644 doc/examples/systemd/ganeti-common.service ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-common.service
install -m 644 doc/examples/systemd/ganeti-confd.service  ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-confd.service
install -m 644 doc/examples/systemd/ganeti-kvmd.service   ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-kvmd.service
install -m 644 doc/examples/systemd/ganeti-luxid.service  ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-luxid.service
install -m 644 doc/examples/systemd/ganeti-metad.service  ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-metad.service
install -m 644 doc/examples/systemd/ganeti-mond.service   ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-mond.service
install -m 644 doc/examples/systemd/ganeti-noded.service  ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-noded.service
install -m 644 doc/examples/systemd/ganeti-rapi.service   ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-rapi.service
install -m 644 doc/examples/systemd/ganeti-wconfd.service ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-wconfd.service

install -m 644 doc/examples/systemd/ganeti-master.target ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-master.target
install -m 644 doc/examples/systemd/ganeti-node.target ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti-node.target
install -m 644 doc/examples/systemd/ganeti.service ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti.service
install -m 644 doc/examples/systemd/ganeti.target ${RPM_BUILD_ROOT}/%{_unitdir}/ganeti.target

install -D -m 644 doc/examples/ganeti.cron ${RPM_BUILD_ROOT}/%{_sysconfdir}/cron.d/%{name}
install -D -m 644 doc/examples/bash_completion ${RPM_BUILD_ROOT}/%{_sysconfdir}/bash_completion.d/%{name}.sh
install -D -m 644 doc/examples/ganeti.default ${RPM_BUILD_ROOT}/%{_sysconfdir}/default/%{name}
install -D -m 644 doc/examples/ganeti.logrotate ${RPM_BUILD_ROOT}/%{_sysconfdir}/logrotate.d/%{name}

mkdir -p ${RPM_BUILD_ROOT}/srv/ganeti/shared-file-storage/{images,os} ${RPM_BUILD_ROOT}/%{_sysconfdir}/%{name}

for man in %{buildroot}/usr/share/%{name}/%{v_minor}/root/usr/share/man/man*/*; do
	gzip ${man}
done
%fdupes -s %{buildroot}/%{py_sitedir}

#%check
#make py-tests-unit
#make py-tests-legacy
#make py-tests-integration
#make hs-tests

%clean
rm -rf ${RPM_BUILD_ROOT}

%pre
%service_add_pre %{name}.service

%post
# This should be used by package installation scripts which require users or
# groups to be present before the files installed by the package are present on
# disk (for example because some files are owned by those users or groups).
#
# Example:
#   Source1: %{name}-sysusers.conf
#   ...
#   %install
#   install -D %SOURCE1 %{buildroot}%{_sysusersdir}/%{name}.conf
#   %pre
#   %sysusers_create_package %{name} %SOURCE1
#   %files
#   %{_sysusersdir}/%{name}.conf
#
# Note: writing to /etc is not recommended on transactional systems but the
# sysusers must be created now since by calling this macro the package explicitly
# requests that.
#
for group in $(< /usr/share/doc/packages/ganeti/users/groups); do
	getent group ${group} || groupadd --system $group
done
while read user pgroup; do
	getent passwd ${user} || useradd --system -d /var/empty -s /bin/false -c "ganeti ${user#gnt-}" -g ${pgroup} ${user}
done < /usr/share/doc/packages/ganeti/users/users
while read user sgroup; do
%if 0%{?suse_version} >= 1315
        usermod -a -G ${sgroup} ${user}
%else
        usermod -A ${sgroup} ${user}
%endif
done < /usr/share/doc/packages/ganeti/users/groupmemberships
# cronjobs as gnt-masterd must run
passwd -x 99999 gnt-masterd
%service_add_post %{name}.service

%preun
%service_del_preun %{name}.service

%postun
%service_del_postun %{name}.service

%files
%defattr(-,root,root)
%config(noreplace) %{_sysconfdir}/default/%{name}
%config %{_unitdir}/*.service
%config %{_unitdir}/*.target
%config %{_sysconfdir}/cron.d/%{name}
%config %{_sysconfdir}/bash_completion.d/%{name}.sh
%config %{_sysconfdir}/logrotate.d/%{name}
#%{_docdir}/%{name}
%{_sbindir}/*
%{_bindir}/*
%dir %{_libdir}/%{name}
%dir %{_datadir}/%{name}
%dir %{_sysconfdir}/cron.d
%{_libdir}/%{name}/*
%{_datadir}/%{name}/*
%{_sysconfdir}/%{name}
#%{py_sitedir}/%{name}
%{_mandir}/man*/*
%dir %{_localstatedir}/lib/%{name}
%dir %{_localstatedir}/log/%{name}
%dir %attr(750,root,root) /srv/%{name}
#%attr(755,root,root) %{py_sitedir}/%{name}/ovf.py
%doc doc/*

%changelog

openSUSE Build Service is sponsored by